|
That's why I do indeed!
Furthermore message are queued in the database in (the unlikely ) case the app crashes. And there is a little app that check the app is alive every 5 seconds.
Oh, and also, we keep (client initiated) connection alive between client and server. This way the server can talk back to clients, since the client don't have a public well know IP available otherwise.
|
|
|
|
|
Congratulations !
cheers, Bill
«There is a spectrum, from "clearly desirable behaviour," to "possibly dodgy behavior that still makes some sense," to "clearly undesirable behavior." We try to make the latter into warnings or, better, errors. But stuff that is in the middle category you don’t want to restrict unless there is a clear way to work around it.» Eric Lippert, May 14, 2008
|
|
|
|
|
Thanks Bill!
Congratulation for your totally unambiguous message this time!
|
|
|
|
|
Super Lloyd wrote: 15 month later, it's government So, what the hurry?
(I'm too working on government related projects, and 15 months to make a decision - like buying hardware - sounds to me a perfectly fast response...)
Skipper: We'll fix it.
Alex: Fix it? How you gonna fix this?
Skipper: Grit, spit and a whole lotta duct tape.
|
|
|
|
|
I just have a laugh at my company who hired me for that "super urgent" project, that is all!!
|
|
|
|
|
You made the right choice for dropping WCF. I still remember the TechEd where they showed 3(ish) lines of code to host WCF... then they opened the config file!
WCF:
Make complex things possible, make simple things complex.
Web API:
An inexperience programmer can make a client in three days.... An experienced programmer can make on in ... three days. Hurray for typing client data objects manually.
Maybe Swagger (or something else) will eventually make it possible to have a decent service definition for REST APIs that can be used across languages without all that typing all the time.
Until then.... I long for the good old days of .net 1.1, where you could create a web service and corresponding client in minutes.
But of course, once we get there (again) some guy is going to say (again) "hmm, we need transactions, let's extend the protocol to support transaction flow"... and "hmm, https is very good, but we have a shared symmetric key, so let's add support for that as well"...
And down the rabbit hole we go again.
|
|
|
|
|
lmoelleb wrote: Web API:
An inexperience programmer can make a client in three days.... An experienced programmer can make on in ... three days. Hurray for typing client data objects manually.
Really that much time?!
I though 2 minute would be plenty enough!
Here is a WebAPI client helper class for ya!
public class WebQueryBuilder
{
StringBuilder url = new StringBuilder();
bool hasParam;
public WebQueryBuilder(string url)
{
this.url = new StringBuilder(url);
hasParam = url.Contains("?");
Method = HttpMethod.Get;
}
public void SetX6509Cert(byte[] rawData, string password)
{
cert = new X509Certificate2(rawData, password);
}
X509Certificate2 cert;
public string this[string key] { set { Add(key, value); } }
public void Add(string key, string value)
{
if (hasParam)
{
url.Append("&");
}
else
{
url.Append("?");
hasParam = true;
}
url.Append(WebUtility.UrlEncode(key));
url.Append("=");
url.Append(WebUtility.UrlEncode(value));
}
public void AddRange(ICollection<KeyValuePair<string, string>> headers)
{
if (headers != null)
foreach (var kv in headers)
Add(kv.Key, kv.Value);
}
public HttpMethod Method { get; set; }
public object Body { get; set; }
public WebHeaderCollection Headers
{
get
{
if (headers == null)
headers = new WebHeaderCollection();
return headers;
}
}
WebHeaderCollection headers;
public DecompressionMethods AutomaticDecompression { get; set; } = DecompressionMethods.None;
public async Task<HttpWebResponse> QueryAsync()
{
var req = (HttpWebRequest)WebRequest.CreateHttp(url.ToString());
req.Method = Method.Method;
if (headers != null)
req.Headers = Headers;
if (cert != null)
req.ClientCertificates.Add(cert);
req.AutomaticDecompression = AutomaticDecompression;
if (HttpMethod.Post.Equals(Method) || HttpMethod.Put.Equals(Method))
{
var tOs = new TaskCompletionSource<IAsyncResult>();
req.BeginGetRequestStream(x => tOs.TrySetResult(x), null);
await tOs.Task;
using (var sOut = (Stream)req.EndGetRequestStream(tOs.Task.Result))
{
if (Body != null)
{
using (var sw = new StreamWriter(sOut, Encoding.UTF8))
using (var jw = new JsonTextWriter(sw))
{
var ser = new JsonSerializer();
ser.Serialize(jw, Body);
}
req.ContentType = "application/json";
}
}
}
var tcs2 = new TaskCompletionSource<IAsyncResult>();
req.BeginGetResponse(x => tcs2.TrySetResult(x), null);
await tcs2.Task;
var wr = (HttpWebResponse)req.EndGetResponse(tcs2.Task.Result);
return wr;
}
public string Url { get { return url.ToString(); } }
public async Task<T> QueryJsonAsync<T>()
{
var wr = await QueryAsync();
ValidateResponse(wr);
return ReadResponse<T>(wr);
}
public static void ValidateResponse(HttpWebResponse wr)
{
if (wr == null)
throw new ArgumentNullException();
bool success = (int)wr.StatusCode >= 200 && (int)wr.StatusCode <= 299;
if (!success)
throw new HttpRequestException($"Problem {wr.StatusCode}: {wr.StatusDescription}");
}
public static T ReadResponse<T>(HttpWebResponse wr)
{
var sResponse = wr.GetResponseStream();
using (var sr = new StreamReader(wr.GetResponseStream()))
using (var js = new JsonTextReader(sr))
{
var ser = new JsonSerializer();
var result = ser.Deserialize<T>(js);
return result;
}
}
public static string ReadResponse(HttpWebResponse wr)
{
var sResponse = wr.GetResponseStream();
using (var sr = new StreamReader(wr.GetResponseStream()))
return sr.ReadToEnd();
}
}
|
|
|
|
|
It is not writing the code calling the API that takes the time.
It's the T on reading, and the object you have to set the body. Where do these come from? Sure, they are SIMPLE to write. But why do we in 2016 have to write simple things ourselves. Isn't that what computers are for?
|
|
|
|
|
Why not use a PCL and share the exact same T class / library on both client and server?
No need to write anything!
(or even the old fashion way, share the data exchange .cs file on both client and server app)
I am really confused why you need to write anything.....
Unless... you mean Web API written by someone else? Some third party?
Mm.... yeah I see that could be tedious.....
Someone should write a code generator for those! haha!
|
|
|
|
|
Yes, it is third party libraries. And some API's from other groups in the company.... using Java. For our internal web APIs we do indeed share the data classes
There are code generators, but they require the web API to be augmented by for example Swagger... and last time I found one of these, Swagger certainly wasn't mature enough to generate anything that would actually work. That might have changed, but it would still require the API to expose Swagger metadata.
|
|
|
|
|
Oh, I would have loved to read the article about this. Sounds very interesting.
|
|
|
|
|
Mmmm... Can't find this article again... Oops.. :'(
A very short and summarized version of it.
You single WCF interface in pseudo code which fudge generic usage
interface IRemote
{
void Execute(Command cmd)
}
interface ICommandHandler<T> where T: Command
{
void Handle(T command);
}
class Service : IRemote
{
public void Execute(Command cmd)
{
IoC.GetCommandHandler(cmd.GetType()).Handle(cmd);
}
}
Additionally you have to write some code that enable to handle data contract (de)serialization of subclass transparently... be inspired by that class
class DataContractSerializerSettings
{
public DataContractResolver DataContractResolver { get; set; }
}
|
|
|
|
|
... Disguised been as a crow what doth upstart.
Actually, Upstart Crow is funnier. Made my day.
I wanna be a eunuchs developer! Pass me a bread knife!
|
|
|
|
|
I missed the first few episodes so now I have to wait for it to be repeated on Dave, five years from now. I wonder if it will still be funny?
|
|
|
|
|
It's on iPlayer[^], but episode 1 has already expired. Episode 2 expires tomorrow at 10:30 PM.
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Yes, I knew I missed it. But it won't be the same unless I can see them all in the right order.
|
|
|
|
|
It's just been picked up for a second series and a Christmas special which suggests that it was possibly successful enough to merit a repeat on t'Beeb erelong, mayhap even a run on BBC1.
I am not a number. I am a ... no, wait!
|
|
|
|
|
It's been on TV, and you're in the UK, so you're legally entitled to watch (and keep) a recorded copy (but not a DVD rip).
I wanna be a eunuchs developer! Pass me a bread knife!
|
|
|
|
|
I needed to do deployment overnight but VPN gave up on me so I decided to be in the office early and do work before business starts work. Made myself a coffee and put it in takeaway cup to drink on the way.Left the house early and try to drink while at signal only to spill all the coffee on my trouser and car seat. Only thing left on my hand was lead and coffee cup decided to dance all over me. Had to drive back home to get changed. So much for waking up early to do the work. Just stepped into office to get a call system is not changed. Fixed it in few minutes and now they are happy. Now I am going to make me a coffee.
Zen and the art of software maintenance : rm -rf *
Maths is like love : a simple idea but it can get complicated.
|
|
|
|
|
There's a lesson to be learned, here, but I confess to not being entirely convinced that it's a lesson that should be learned.
Unless what you take away is that Murphy really does rule the world. That I'm absolutely convinced of.
I wanna be a eunuchs developer! Pass me a bread knife!
|
|
|
|
|
Never let em see you sweat.
|
|
|
|
|
Despite some personal interest I didn't spend much (and nearly enough) time playing with Crysis, Unity or Xenko engine.
One question that came to my mind though.. As I was playing "Torment Tide of Numenera" pre release (made with Unity and very small map), they seam to all come with the concept of a rectangular map / level.
And when you move out of it.. well you are loading the next one... Can be long.. (is painfully slow in Torment, like in those RPG of yore)
So I wonder.. How come in, say, Skyrim, I can see the whole country (If I climb to the tallest mountain first though hey!) or / and in Fallout I can freely move about, never a loading screen!
(well going in / out of town / house seem to trigger it) but I can still wander the wilderness for kilometers and spot things far ahead!
How does that works?
[EDIT]
Well, yeah, I suspect They automatically generate a simplified world map for long distance vision and always have the 8 neighboring maps preloaded in the background for smooth transition...
I just wondered if there is more to it.. Otherwise why did it take so long for this to be the norm?
modified 13-Jun-16 18:14pm.
|
|
|
|
|
Magic! Obviously!
I am not a number. I am a ... no, wait!
|
|
|
|
|
Of course!
So Simple!
|
|
|
|
|
There are different game maps: rectangular, circular (leaving the left side brings you back on the right), circular with dynamic links, generated...and the combination of these
As for the loading - background loading is an old trick, I had games on C64 using it...
Skipper: We'll fix it.
Alex: Fix it? How you gonna fix this?
Skipper: Grit, spit and a whole lotta duct tape.
|
|
|
|