// 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);
            }
        }
예제 #2
0
        // 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);
        }
예제 #3
0
        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);
        }
예제 #4
0
        // 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)));
        }
예제 #5
0
        // 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);
        }
예제 #6
0
 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));
 }
예제 #7
0
        // 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);
        }
예제 #8
0
        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.LogDebug, "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, (data) =>
            {
                try
                {
                    Messenger.Broadcast(SympleLog.LogInfo, "symple:client: disconnect");

                    string msg = (string)data;
                    Messenger.Broadcast(SympleLog.LogInfo, "symple:client: disconnect msg: " + msg);

                    Messenger.Broadcast(SympleLog.Disconnect);
                    this.peer["online"] = false;
                    this.dispatch("disconnect");
                }
                catch (Exception e)
                {
                    Messenger.Broadcast(SympleLog.LogInfo, "caught exception: " + e.Message);
                }
            });
#endif
        }