public void RemoveSubscriber(WsConfSubscriber subscriber)
 {
     lock (this)
     {
         if (noOfModifiers++ == 0)
         {
             hashSetChangeDone.Reset();
         }
         if (noOfBroadcasters > 0)
         {
             Monitor.Wait(this);
         }
     }
     try
     {
         subscribers.Remove(subscriber);
         if (disposedSubs != null)
         {
             disposedSubs.Remove(subscriber);
         }
     }
     finally
     {
         lock (this)
         {
             if (--noOfModifiers == 0)
             {
                 hashSetChangeDone.Set();
             }
         }
     }
 }
    public Boolean AddSubscriber(WsConfSubscriber subscriber)
    {
        bool result = false;

        lock (this)
        {
            if (noOfModifiers++ == 0)
            {
                hashSetChangeDone.Reset();
            }
            if (noOfBroadcasters > 0)
            {
                Monitor.Wait(this);
            }
        }
        try
        {
            logger.Info(subscribers + ";" + subscriber);
            result = subscribers.Add(subscriber);
        }
        finally
        {
            lock (this)
            {
                if (--noOfModifiers == 0)
                {
                    hashSetChangeDone.Set();
                }
            }
        }
        return(result);
    }
    public async Task OnOpen(WsConfSubscriber subscriber)
    {
        WsConfPubSubState confState;
        Boolean           substate = false;

        if (!channels.TryGetValue(channelName, out confState))
        {
            confState = channels.GetOrAdd(channelName, new WsConfPubSubState());
        }
        substate = confState.AddSubscriber(subscriber);
        String sendLog = "{\"Action\" : \"open\",\"host\":\" "
                         + remoteHost + "\",\"port\": "
                         + remotePort + ", \"subscribe\":"
                         + (substate ? "true" : "false")
                         + ",\"subscount\":" + confState.GetSubscribersCount() + "}";
        ArraySegment <byte> welcomeBuffer = new ArraySegment <byte>(Encoding.UTF8.GetBytes(sendLog));
        Boolean             gotSignal     = false;

        try
        {
            gotSignal = subscriber.autoREvent.WaitOne();
            await subscriber.subSocket.SendAsync(welcomeBuffer, WebSocketMessageType.Text, true, CancellationToken.None);
        }
        finally
        {
            if (gotSignal)
            {
                subscriber.autoREvent.Set();
            }
        }
        logger.Info("OnOpen " + channelName + "-->" + sendLog);
    }
    public void OnClose(WsConfSubscriber subsciber, WebSocketCloseStatus status)
    {
        WsConfPubSubState confState;

        if (channels.TryGetValue(channelName, out confState))
        {
            confState.RemoveSubscriber(subsciber);
        }
        String sendLog = "{\"Action\" : \"close\",\"host\":\" " + remoteHost + "\",\"port\": " + remotePort + ",\"subscount\":" + confState.GetSubscribersCount() + ",\"CloseStatus\": " + status + "}";

        logger.Info("OnClose " + channelName + "-->" + sendLog);
    }
    private async Task HandleWebSocket(WebSocketContext wsContext)
    {
        const int maxMessageSize = 1024;

        byte[]           receiveBuffer = new byte[maxMessageSize];
        WebSocket        subSocket     = wsContext.WebSocket;
        WsConfSubscriber subscriber    = new WsConfSubscriber(subSocket);

        await OnOpen(subscriber);

        while (subSocket.State == WebSocketState.Open)
        {
            WebSocketReceiveResult receiveResult = null;
            try
            {
                receiveResult = await subSocket.ReceiveAsync(new ArraySegment <byte>(receiveBuffer), CancellationToken.None);
            }
            catch (WebSocketException wse)
            {
                OnClose(subscriber, WebSocketCloseStatus.InvalidMessageType);
                logger.Error("Error at ReceiveAsync", wse);
                break;
            }

            if (receiveResult.MessageType == WebSocketMessageType.Close)
            {
                OnClose(subscriber, receiveResult.CloseStatus.Value);
                await subSocket.CloseOutputAsync(WebSocketCloseStatus.NormalClosure, string.Empty, CancellationToken.None);
            }
            else if (receiveResult.MessageType == WebSocketMessageType.Binary)
            {
                OnClose(subscriber, WebSocketCloseStatus.InvalidMessageType);
                await subSocket.CloseAsync(WebSocketCloseStatus.InvalidMessageType, "Binary frame not allowed", CancellationToken.None);
            }
            else
            {
                int count = receiveResult.Count;
                while (receiveResult.EndOfMessage == false)
                {
                    if (count >= maxMessageSize)
                    {
                        string closeMessage = string.Format("Max message size: {0} bytes.", maxMessageSize);
                        OnClose(subscriber, WebSocketCloseStatus.MessageTooBig);
                        await subSocket.CloseAsync(WebSocketCloseStatus.MessageTooBig, closeMessage, CancellationToken.None);

                        return;
                    }
                    receiveResult = await subSocket.ReceiveAsync(new ArraySegment <byte>(receiveBuffer, count, maxMessageSize - count), CancellationToken.None);

                    if (receiveResult.Count == 0)
                    {
                        logger.Info("onReceiveAsync " + channelName + "--> BytesCount:0");
                    }
                    count += receiveResult.Count;
                }
                //var receivedString = Encoding.UTF8.GetString(receiveBuffer, 0, count);
            }
        }
        String sendLog = "{\"Action\" : \"close\",\"host\":\" " + remoteHost + "\",\"port\": " + remotePort + "}";

        logger.Info("outOfWhile " + channelName + "-->" + sendLog);
    }