// called when local SDP is ready to be sent to the peer private async void _onLocalSDP(RTCSessionDescription desc) { try { Messenger.Broadcast(SympleLog.LogTrace, "symple:webrtc: _onLocalSDP"); string localSdp = desc.Sdp; Messenger.Broadcast(SympleLog.LogTrace, "symple:webrtc: localSdp = " + localSdp); List <int> localVideoCodecIds = Symple.GetVideoCodecIds(localSdp); string logMsg = "localVideoCodecIds: "; foreach (var videoCodecId in localVideoCodecIds) { logMsg += videoCodecId + " "; } Messenger.Broadcast(SympleLog.LogTrace, "symple:webrtc: " + logMsg); await this.pc.SetLocalDescription(desc); this.sendLocalSDP(desc); } catch (Exception e) { Messenger.Broadcast(SympleLog.LogError, "symple:webrtc: failed to send local SDP; " + e); } }
// dispatch function for handling filtered message response callbacks private bool dispatchResponse(string eventLabel, params object[] arguments) { var data = arguments; if (this.listeners.ContainsKey(eventLabel)) { List <object> listenersForEvent = listeners[eventLabel]; foreach (object listenerForEvent in listenersForEvent) { if (listenerForEvent.GetType() == typeof(JObjectWithActions)) { JObjectWithActions listenerObj = (JObjectWithActions)listenerForEvent; if (listenerObj["filters"] != null) { { JObject filtersObj = (JObject)listenerObj["filters"]; JObject dataObj = (JObject)data[0]; if (Symple.match(filtersObj, dataObj)) { Action <object> fn = listenerObj.actions["fn"]; fn(data); if (listenerObj["after"] != null) { Action <object> after = listenerObj.actions["after"]; after(data); } return(true); } } } } } } return(false); }
// get the peer matching an ID or address string: user|id public override JObject get(string id) { // handle IDs JObject peer = base.get(id); if (peer != null) { return(peer); } // handle address strings return(this.findOne(Symple.parseAddress(id))); }
// remove the peer matching an ID or address string: user|id public override JObject remove(string id) { var addr = Symple.parseAddress(id); id = (string)addr["id"] ?? id; var peer = base.remove(id); if (peer != null) { this.client.dispatch("removePeer", peer); } return(peer); }
public List <JObject> find(JObject parameters) { List <JObject> res = new List <JObject>(); for (int i = 0; i < this.store.Count; i++) { if (Symple.match(parameters, this.store[i])) { res.Add(this.store[i]); } } return(res); }
public void sendPresence(JObject p) { p = p ?? new JObject(); if (p["data"] != null) { JObject pDataObj = (JObject)p["data"]; p["data"] = Symple.merge(this.peer, pDataObj); } else { p["data"] = this.peer; } this.send(new SymplePresence(p)); }
// send a message to the given peer // m = JSON object // to = either a string or a JSON object to build an address from #if NETFX_CORE public void send(JObject m, JToken to = null) { if (!this.online()) { 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"] = Symple.buildAddress(this.peer); if (m["from"] == m["to"]) { throw new Exception("message sender cannot match the recipient"); } Messenger.Broadcast(SympleLog.LogTrace, "symple:client: sending" + m); this.socket.Send(m); }
public void connect() { #if NETFX_CORE Messenger.Broadcast(SympleLog.LogInfo, "symple:client: connecting"); if (this.socket != null) { string err = "the client socket is not null"; Messenger.Broadcast(SympleLog.LogError, err); throw new Exception(err); } this.socket = IO.Socket(this.options["url"].ToString(), this.ioOptions); this.socket.On(Socket.EVENT_CONNECT, () => { Messenger.Broadcast(SympleLog.LogInfo, "symple:client: connected"); Messenger.Broadcast(SympleLog.Connected); JObject announceData = new JObject(); announceData["user"] = this.peer["user"] ?? ""; announceData["name"] = this.peer["name"] ?? ""; announceData["type"] = this.peer["type"] ?? ""; announceData["token"] = options["token"] ?? ""; string announceDataJsonString = JsonConvert.SerializeObject(announceData, Formatting.None); Messenger.Broadcast(SympleLog.LogTrace, "announceDataJsonString: " + announceDataJsonString); this.socket.Emit("announce", (resObj) => { Messenger.Broadcast(SympleLog.LogDebug, "symple:client: announced " + resObj); Messenger.Broadcast(SympleLog.Announced); JObject res = (JObject)resObj; if ((int)res["status"] != 200) { this.setError("auth", resObj.ToString()); return; } JObject resData = (JObject)res["data"]; this.peer = Symple.extend(this.peer, resData); this.roster.add(resData); JObject sendPresenceParams = new JObject(); sendPresenceParams["probe"] = true; this.sendPresence(sendPresenceParams); this.dispatch("announce", res); this.socket.On(Socket.EVENT_MESSAGE, (msg) => { Messenger.Broadcast(SympleLog.LogTrace, "symple:client receive " + msg); JObject m = (JObject)msg; string mType = (string)m["type"]; switch (mType) { case "message": m = new SympleMessage(m); break; case "command": m = new SympleCommand(m); break; case "event": m = new SympleEvent(m); break; case "presence": m = new SymplePresence(m); if ((bool)m["data"]["online"]) { this.roster.update((JObject)m["data"]); } else { this.roster.remove((string)m["data"]["id"]); } if (m["probe"] != null && (bool)m["probe"] == true) { JObject presenceTo = new JObject(); presenceTo["to"] = Symple.parseAddress(m["from"].ToString())["id"]; this.sendPresence(new SymplePresence(presenceTo)); } break; default: var o = m; o["type"] = o["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 rpeer = this.roster.get(mFrom); if (rpeer != null) { Messenger.Broadcast(SympleLog.LogTrace, "found rpeer: " + rpeer); m["from"] = rpeer; } else { Messenger.Broadcast(SympleLog.LogInfo, "symple:client: got message from unknown peer: " + m); } // Dispatch to the application this.dispatch((string)m["type"], m); }); }, announceData); }); this.socket.On(Socket.EVENT_ERROR, () => { // this is triggered when any transport fails, so not necessarily fatal this.dispatch("connect"); }); this.socket.On("connecting", () => { Messenger.Broadcast(SympleLog.LogDebug, "symple:client: connecting"); this.dispatch("connecting"); }); this.socket.On(Socket.EVENT_RECONNECTING, () => { Messenger.Broadcast(SympleLog.LogDebug, "symple:client: connecting"); Messenger.Broadcast(SympleLog.Reconnecting); this.dispatch("reconnecting"); }); this.socket.On("connect_failed", () => { // called when all transports fail Messenger.Broadcast(SympleLog.LogError, "symple:client: connect failed"); Messenger.Broadcast(SympleLog.ConnectFailed); this.dispatch("connect_failed"); this.setError("connect"); }); this.socket.On(Socket.EVENT_DISCONNECT, () => { Messenger.Broadcast(SympleLog.LogInfo, "symple:client: disconnect"); Messenger.Broadcast(SympleLog.Disconnect); this.peer["online"] = false; this.dispatch("disconnect"); }); #endif }