public SubscriptionList(Socket socket)
 {
     _subscribedSockets = new ConcurrentDictionary<int, Socket>
     {
         [socket.GetHashCode()] = socket
     };
 }
Esempio n. 2
0
 public void UnSubscribe(string topic, Socket socket)
 {
     SubscriptionList topicSubscribers;
     if (!_subscriptions.TryGetValue(topic, out topicSubscribers))
         return;
     topicSubscribers.Remove(socket);
 }
Esempio n. 3
0
        internal JoinResult Join(string topic, Socket socket)
        {
            var attr = _channelTopics.Keys.FirstOrDefault(a => a.IsMatch(topic));
            if (attr == null)
                throw new Exception($"Unable to route ${topic} to a channel topic in class ${GetType()}");

            MethodInfo action;
            if (!_channelTopics.TryGetValue(attr, out action))
                throw new Exception($"Unable to get channel join action for topic {topic}.");
            
            if (!attr.HasBoundSubtopic)
                return action.Invoke(this, new object[] { socket }) as JoinResult;

            var boundParam = attr.GetBoundSubtopic(topic);
            var paramsInfo = action.GetParameters();
            var args = new object[paramsInfo.Length];
            for (int i = 0; i < paramsInfo.Length; i++)
            {
                var paramInfo = paramsInfo[i];
                if (paramInfo.ParameterType == typeof(Socket))
                    args[i] = socket;
                else if (paramInfo.Name == boundParam.Name && paramInfo.ParameterType == typeof(string))
                    args[i] = boundParam.Value;
                else
                    throw new Exception($"Unable to bind param {paramInfo.Name}.");
            }
            return action.Invoke(this, args) as JoinResult;
        }
        /// <summary>
        /// Creates a socket and dispatches it and a message to a channel.
        /// </summary>
        protected Task Dispatch(Message message)
        {
            if (message == null)
                return Task.FromResult(0);

            var channel = Channel.MatchTopic(message.Topic);
            var socket = new Socket(this, _pubSub, channel, message.Topic);

            switch (message.Event)
            {
                case "phx_join":
                    return JoinChannel(socket, message);
                case "phx_leave":
                    return LeaveChannel(socket, message);
                case "heartbeat":
                    return Heartbeat(socket, message);
                default:
                    return DispatchMessage(socket, message);
            }
        }
 public void Remove(Socket socket)
 {
     Socket _;
     _subscribedSockets.TryRemove(socket.GetHashCode(), out _);
 }
 public bool Add(Socket socket) => _subscribedSockets.TryAdd(socket.GetHashCode(), socket);
Esempio n. 7
0
 public Task Broadcast(Socket socket, string @event, JObject payload) => Broadcast(socket.Topic, @event, payload);
Esempio n. 8
0
 public void Subscribe(string topic, Socket socket)
 {
     var subscriptionList = _subscriptions.GetOrAdd(topic, _key => new SubscriptionList(socket));
     subscriptionList.Add(socket);
 }
 /// <summary>
 /// Dispatches a message to a channel.
 /// </summary>
 /// <param name="message"></param>
 /// <returns></returns>
 protected static async Task DispatchMessage(Socket socket, Message message)
 {
     var eventResult = await socket.Channel.HandleIn(message, socket);
     switch(eventResult.ResultAction)
     {
         case EventResult.Action.NoReply:
             return;
         case EventResult.Action.Reply:
             await socket.Transport.SendReply(new Reply(message.Ref, message.Topic, eventResult.Status, eventResult.Response));
             return;
         case EventResult.Action.Stop:
             // ??
             return;
     }
 }
 /// <summary>
 /// Converts a heartbeat message to a heartbeat reply.
 /// </summary>
 protected static Task Heartbeat(Socket socket, Message message) => socket.Transport.SendReply((new Reply(message.Ref, message.Topic, "ok", new JObject())));
 protected static Task LeaveChannel(Socket socket, Message message)
 {
     return null;
 }
 /// <summary>
 /// Subscribes to a channel topic.
 /// </summary>
 protected static Task JoinChannel(Socket socket, Message message)
 {
     JObject payload;
     string status;
     var joinResult = socket.Channel.Join(message.Topic, socket);
     if (joinResult.Success)
     {
         socket.PubSub.Subscribe(message.Topic, socket);
         status = "ok";
         payload = joinResult.Response;
     }
     else
     {
         status = "error";
         payload = new JObject(joinResult.Error);
     }
     return socket.Transport.SendReply(new Reply(message.Ref, message.Topic, status, payload));
 }
Esempio n. 13
0
 public static Task Push(Socket socket, string @event, JObject payload)
 {
     var broadcast = new Broadcast(socket.Topic, @event, payload);
     return socket.Transport.SendBroadcast(broadcast);
 }
Esempio n. 14
0
 public static Task Broadcast(Socket socket, string @event, JObject payload)
 {
     return socket.PubSub.Broadcast(socket, @event, payload);
 }
Esempio n. 15
0
        internal async Task<EventResult> HandleOut(string @event, JObject payload, Socket socket)
        {
            var attr = _outgoingEvents.Keys.FirstOrDefault(a => a.IsMatch(@event));
            if (attr == null)
            {
                await Push(socket, @event, payload);
                return EventResult.NoReply;
            }

            MethodInfo action;
            if (!_outgoingEvents.TryGetValue(attr, out action))
                throw new Exception($"Unable to get channel handle out hook for event {@event}.");

            return await (action.Invoke(this, new object[] { payload, socket }) as Task<EventResult>);
        }
Esempio n. 16
0
        internal async Task<EventResult> HandleIn(Message message, Socket socket)
        {
            var attr = _incomingEvents.Keys.FirstOrDefault(a => a.IsMatch(message.Event));
            if (attr == null)
                throw new Exception($"Unable to route ${message.Event} to a channel incoming event hook in class ${GetType()}");

            MethodInfo action;
            if (!_incomingEvents.TryGetValue(attr, out action))
                throw new Exception($"Unable to get channel handle in hook for event {message.Event}.");

            return await (action.Invoke(this, new object[] { message.Payload, socket }) as Task<EventResult>);
        }