/// <summary> /// Broadcasts a position message to all online users /// </summary> /// <param name="Message">The chat message to be broadcasted</param> /// <param name="AContext">The user's connection context</param> private static void SetPosition(RCATContext RContext, ServerMessage message) { try { User user = new User(); user = (User)serializer.Deserialize(new JTokenReader(message.Data), typeof(User)); dataConnector.SetPosition(user.n, user.p, message.TimeStamp); string[] clients = dataConnector.GetAllUsersNames(); dynamic data = new { n = user.n, p = user.p }; RContext.Broadcast(data, clients, ResponseType.Position, message.TimeStamp); } catch (Exception e) { Log.Error(e); } }
/// <summary> /// Informs a user of all the existing clients. /// </summary> private static void SendAllUsers(RCATContext RContext, string client) { try { ClientMessage r = new ClientMessage(); r = new ClientMessage(); r.Type = ResponseType.AllUsers; r.clients = new string[1]; r.clients[0] = client; // Using database User[] arr = dataConnector.GetAllUsers(); r.Data = new { Users = arr }; RContext.Send(JsonConvert.SerializeObject(r)); } catch (Exception e) { Log.Error("Exception in SendAllUsers:",e); } }
protected static void RunServer(IAsyncResult AResult) { // Server connection //TcpClient TcpConnection = null; try { proxy.EndConnect(AResult); } catch (Exception e) { Log.Error("Connect Failed", e); } if (proxy != null) { using (RCATContext RContext = new RCATContext()) { try { RContext.proxyConnection = proxy; while (proxy.Connected) { if (RContext.ReceiveReady.Wait(TimeOut)) { proxy.Client.BeginReceive(RContext.buffer, 0, RCATContext.DefaultBufferSize, SocketFlags.None, new AsyncCallback(DoReceive), RContext); } else { Log.Warn("[RCAT]: Server timed out connection with proxy."); break; } } } catch (Exception e) { Log.Warn("Server Forcefully Disconnected", e); } } } }
// Handles the server request. Broadcast is the only server side functionality at this point. protected static void HandleRequest(RCATContext context, List<string> commands) { int i = 0; //index in server.sb foreach (string s in commands) { try { if (s != "") { Log.Info("[PROXY->SERVANT]: Received: " + s); ServerMessage message = Newtonsoft.Json.JsonConvert.DeserializeObject<ServerMessage>(s); // a bug happens at this line when the servant has to concatenate multiple JSON msg together if (message.Type == ResponseType.Connection) OnConnect(context, message); else if (message.Type == ResponseType.Disconnect) OnDisconnect(context, message); else if (message.Type == ResponseType.Position) SetPosition(context, message); else Log.Warn("[RCAT]: Unknown message.Type: " + message.Type.ToString()); i++; } } catch { Log.Warn("[RCAT]: Error parsing JSON in RCAT.HandleRequest. JSON message was: " + commands[i]); //Log.Debug(e);s } } }
// 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); } }
/// <summary> /// Event fired when a client connects to the Alchemy Websockets server instance. /// Adds the client to the online users list. /// </summary> /// <param name="AContext">The user's connection context</param> public static void OnConnect(RCATContext RContext, ServerMessage message) { try { Log.Info("Client Connection From : " + (string)message.Data); SendAllUsers(RContext, message.Data); } catch (Exception e) { Log.Error("Exception in OnConnect", e); } }