private void removePeerFromRoster(string peerServerId) { Debug.WriteLine("removePeerFromRoster " + peerServerId); var addr = Symple.parseAddress(peerServerId); Debug.WriteLine("addr " + addr); peerServerId = (string)addr["id"] ?? peerServerId; if (_roster.ContainsKey(peerServerId)) { var peer = _roster[peerServerId]; int peerLocalIntId = peer.localIntId; _roster.Remove(peerServerId); _localIntIdsToServerIds.Remove(peerLocalIntId); RaiseOnPeerDisconnected(peerLocalIntId); } else { Debug.WriteLine("could not find peerServerId " + peerServerId + " in roster"); } }
// send a message to the given peer // m = JSON object // to = either a string or a JSON object to build an address from public void send(JObject m, JToken to = null) { Debug.WriteLine("SympleSignaller:send: " + m + " " + to); if (!IsConnected()) { throw new Exception("cannot send messages while offline"); // TODO: add to pending queue? } if (m.Type != JTokenType.Object) { throw new Exception("message must be an object"); } if (m["type"].Type != JTokenType.String) { m["type"] = "message"; } if (m["id"] == null) { m["id"] = Symple.randomString(8); } if (to != null) { m["to"] = to; } if (m["to"] != null && m["to"].Type == JTokenType.Object) { JObject mToObj = (JObject)m["to"]; m["to"] = Symple.buildAddress(mToObj); } if (m["to"] != null && m["to"].Type != JTokenType.String) { throw new Exception("message 'to' attribute must be an address string"); } m["from"] = buildAddress(_myPeerData); if (m["from"] == m["to"]) { throw new Exception("message sender cannot match the recipient"); } Messenger.Broadcast(SympleLog.LogTrace, "symple:client: sending" + m); _socket.Send(m); }
private void sendPresence(JObject p) { p = p ?? new JObject(); if (p["data"] != null) { JObject pDataObj = (JObject)p["data"]; p["data"] = Symple.merge(peerDataToJObject(_myPeerData), pDataObj); } else { p["data"] = peerDataToJObject(_myPeerData); } p["type"] = "presence"; this.send(p); }
private string buildAddress(PeerData pd) { return(Symple.buildAddress(peerDataToJObject(pd))); }
private Dictionary <int, string> _localIntIdsToServerIds; // maps local int ids to server ids private void SignallerOnMessage(string mType, JObject m) { Debug.WriteLine("SignallerOnMessage " + mType + " " + m); // here we process what the webrtccontext would normally do when a new message comes in. // so we adjust the message and pass it on to the Conductor. string fromServerId; var mFromObj = m["from"] as JObject; if (mFromObj != null) { fromServerId = (string)mFromObj["id"]; } else { fromServerId = (string)m["from"]; // string instead of json object } JObject parsedAddress = Symple.parseAddress(fromServerId); // handle case where "from" is name|id fromServerId = (string)parsedAddress["id"] ?? fromServerId; if (_roster.ContainsKey(fromServerId)) { PeerData fromPd = _roster[fromServerId]; int fromLocalIntId = fromPd.localIntId; if (m["offer"] != null) { Debug.WriteLine("incoming offer message"); JObject messageForConductor = (JObject)m["offer"]; RaiseOnMessageFromPeer(fromLocalIntId, messageForConductor.ToString(Formatting.None)); } else if (m["answer"] != null) { Debug.WriteLine("incoming answer message"); JObject messageForConductor = (JObject)m["answer"]; RaiseOnMessageFromPeer(fromLocalIntId, messageForConductor.ToString(Formatting.None)); } else if (m["candidate"] != null) { Debug.WriteLine("incoming candidate message"); JObject messageForConductor = (JObject)m["candidate"]; RaiseOnMessageFromPeer(fromLocalIntId, messageForConductor.ToString(Formatting.None)); } else if (mType == "presence") { // the presence messages are handled earlier in the signalling code, so at this point, do nothing with them. } else if (m["message"] != null) { JObject messageForConductor = m; // send the entire raw message! the "message" format will route it correctly RaiseOnMessageFromPeer(fromLocalIntId, messageForConductor.ToString(Formatting.None)); } else { // the content of the message is unrecognized by the signaller Debug.WriteLine("TODO: incoming misc message of type " + m["type"]); } } else { Debug.WriteLine("received message from unknown sender " + fromServerId); } }
private void SocketOnMessage(object msg) { Messenger.Broadcast(SympleLog.LogTrace, "SocketOnMessage: " + msg); JObject m = (JObject)msg; string mType = (string)m["type"]; switch (mType) { case "message": break; case "command": break; case "event": break; case "presence": JObject remotePeerData = (JObject)m["data"]; // data about another peer that has been updated or removed bool remotePeerOnline = (bool)remotePeerData["online"]; if (remotePeerOnline) { addOrUpdatePeerToRoster(remotePeerData); } else { string remotePeerServerId = (string)remotePeerData["id"]; removePeerFromRoster(remotePeerServerId); } if (m["probe"] != null && (bool)m["probe"] == true) { JObject presenceTo = new JObject(); presenceTo["to"] = Symple.parseAddress(m["from"].ToString())["id"]; this.sendPresence(presenceTo); } break; default: m["type"] = m["type"] ?? "message"; break; } if (m["from"].Type != JTokenType.String) { Messenger.Broadcast(SympleLog.LogError, "symple:client: invalid sender address: " + m); return; } // replace the from attribute with the full peer object. // this will only work for peer messages, not server messages. string mFrom = (string)m["from"]; Messenger.Broadcast(SympleLog.LogTrace, "looking up rpeer in roster, mFrom = " + mFrom + "..."); var addr = Symple.parseAddress(mFrom); Debug.WriteLine("addr " + addr); mFrom = (string)addr["id"] ?? mFrom; if (_roster.ContainsKey(mFrom)) { PeerData rpeerData = _roster[mFrom]; Messenger.Broadcast(SympleLog.LogTrace, "found rpeerData: " + rpeerData); m["from"] = peerDataToJObject(rpeerData); } else { Messenger.Broadcast(SympleLog.LogDebug, "symple:client: got message from unknown peer: " + m); } // Dispatch to the application SignallerOnMessage(mType, m); }