/// <summary> /// notify a server that a client just connected /// </summary> /// <param name="client"></param> public void SendClientConnect(UserContext client) { ServerContext server = PickServer(); Message resp = new Message(); resp.Type = ResponseType.Connection; resp.Data = client.ClientAddress.ToString(); server.Send(Newtonsoft.Json.JsonConvert.SerializeObject(resp)); }
/// <summary> /// Sends an error message to the client who caused the error /// </summary> /// <param name="ErrorMessage">Details of the error</param> /// <param name="AContext">The user's connection context</param> private static void SendError(string ErrorMessage, UserContext AContext, ServerMessage message) { Log.Warn("Error Message: " + ErrorMessage); Message r = new Message(); r = new Message(); r.Type = ResponseType.Error; r.Data = new { Message = ErrorMessage }; //AContext.Send(JsonConvert.SerializeObject(r)); }
// NOTE: This is not safe code. You may end up broadcasting to people who // disconnected. Luckily for us, Alchemy handles exceptions in its event methods, so we don't // have random, catastrophic changes. /// <summary> /// Event triggered when a user disconnected from a proxy /// Remove a user from the online users list /// and broadcast the disconnection message to all connected users. /// </summary> /// <param name="AContext">The user's connection context</param> public static void OnDisconnect(RCATContext RContext, ServerMessage message) { try { Log.Info("[PROXY->SERVANT]: User disconnected: " + message.Data); User user = dataConnector.GetUser(message.Data); Message r = new Message(); if (!String.IsNullOrEmpty(user.n)) { dataConnector.RemoveUser(user.n); string[] clients = dataConnector.GetAllUsersNames(); RContext.Broadcast(new { n = user.n }, clients, ResponseType.Disconnect, message.TimeStamp); } else Log.Warn("[PROXY->SERVANT]: User " + user.n + " not found OnDisconnect."); } catch (Exception e) { Log.Error("[PROXY->SERVANT]: Error in OnDisconnect.",e); } }
public void SendToClient(ClientMessage message) { string name = message.clients[0]; UserContext user = Proxy.onlineUsers[name]; try { Message m = new Message(); m.Type = message.Type; m.Data = message.Data; string json = JsonConvert.SerializeObject(m); user.Send(json); } catch { Log.Debug("[PROXY->CLIENT]: User " + user + " not found."); } }
/// <summary> ///send the same data to multiple clients (broadcast contains the data to send and the array of clients to send to) /// </summary> /// <param name="broadcast"></param> public void BroadcastToClients(ClientMessage broadcast) { try { string name = (string)broadcast.Data.SelectToken("n"); UserContext user = null; if (Proxy.onlineUsers.ContainsKey(name)) user = Proxy.onlineUsers[name]; else { Log.Debug("User " + name + " not present in this Proxy"); return; } long lastupdate = user.LastUpdate; if (broadcast.Type == ResponseType.Disconnect) lastupdate = 0; // Just to be sure it will enter next if user.SendingSemaphore.Wait(); if (broadcast.TimeStamp >= lastupdate) { user.LastUpdate = broadcast.TimeStamp; Message m = new Message(); m.Type = broadcast.Type; m.Data = broadcast.Data; string json = JsonConvert.SerializeObject(m); foreach (string client in broadcast.clients) { try { UserContext cl = Proxy.onlineUsers[client]; cl.Send(json); } catch { Log.Debug("[PROXY->CLIENT]: User " + client + " not found."); } } } else { user.LatePackets++; user.SendingSemaphore.Release(); return; } if (broadcast.Type == ResponseType.Disconnect) { if (Proxy.onlineUsers.ContainsKey(name)) Proxy.onlineUsers.Remove(name); } else { user.SentCounter--; if (user.SentCounter <= 0 && lastupdate > 0) { user.SentCounter = UserContext.DefaultSentCounter; long timetoprocess = user.TimeToProcess; LoggingObject logobj = new LoggingObject(broadcast.TimeStamp, user, timetoprocess); ThreadPool.QueueUserWorkItem(new WaitCallback(LogRoundTrip), logobj); user.TimeToProcess = DateTime.Now.Ticks; } } user.SendingSemaphore.Release(); } catch (Exception e) { Log.Error(e); } }