Ejemplo n.º 1
0
        /// <summary>
        /// 保存历史消息
        /// </summary>
        /// <param name="data"></param>
        public static void SaveHistoricalMessg(ChatData data)
        {
            var size = 40;

            lock (lockSaveMsg)
            {
                historicalMessg.Add(data);
            }
            if (historicalMessg.Count >= size)
            {
                lock (lockSaveMsg)
                {
                    historicalMessg.RemoveRange(0, 30);
                }
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// 发送消息到所有人
        /// </summary>
        /// <param name="sockets"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        public async static Task SendToWebSocketsAsync(List <WebSocket> sockets, ChatData data)
        {
            SaveHistoricalMessg(data);//保存历史消息
            var chatData = JsonConvert.SerializeObject(data);
            var buffer   = Encoding.UTF8.GetBytes(chatData);
            ArraySegment <byte> arraySegment = new ArraySegment <byte>(buffer);

            //循环发送消息
            for (int i = 0; i < sockets.Count; i++)
            {
                var tempsocket = sockets[i];
                if (tempsocket.State == WebSocketState.Open)
                {
                    //发送消息
                    await tempsocket.SendAsync(arraySegment, WebSocketMessageType.Text, true, CancellationToken.None);
                }
            }
        }
Ejemplo n.º 3
0
        public static List <ChatData> historicalMessg = new List <ChatData>();//存放歷史消息--後續改為數據庫存儲。

        static async Task Acceptor(HttpContext httpContext, Func <Task> n)
        {
            if (!httpContext.WebSockets.IsWebSocketRequest)
            {
                return;
            }
            //建立一个WebSocket连接请求
            var socket = await httpContext.WebSockets.AcceptWebSocketAsync();

            //判断限制最大连接数
            if (_sockets.Count >= 100)
            {
                //限制加入
                await socket.CloseAsync(WebSocketCloseStatus.PolicyViolation, "链接超过最大限制,请稍后加入群聊...", CancellationToken.None);

                return;
            }
            lock (objLock)
            {
                _sockets.Add(socket);//加入群聊
            }
            var buffer = new byte[BufferSize];

            //根据请求头获取用户名
            string userName = httpContext.Request.Query["userName"].ToString();

            var chatData = new ChatData()
            {
                Info = $"{userName}进入房间。当前在线{_sockets.Count}人~~~"
            };

            //群发上线通知
            await SendToWebSocketsAsync(_sockets, chatData);

            while (true)
            {
                try
                {
                    //建立连接,阻塞等待接收消息
                    var incoming = await socket.ReceiveAsync(new ArraySegment <byte>(buffer), CancellationToken.None);

                    //如果主动退出,则移除
                    if (incoming.MessageType == WebSocketMessageType.Close)
                    {
                        lock (objLock)
                        {
                            _sockets.Remove(socket);//移除用户
                        }
                        chatData = new ChatData()
                        {
                            Info = $"{userName}离开房间。还剩{_sockets.Count}~~~"
                        };
                        await SendToWebSocketsAsync(_sockets, chatData);

                        break;//这里一定要跳出循环
                    }
                    var chatDataStr = await ArraySegmentToStringAsync(new ArraySegment <byte>(buffer, 0, incoming.Count));

                    if (chatDataStr == "heartbeat")//如果是心跳检查,则直接跳过
                    {
                        continue;
                    }
                    chatData      = JsonConvert.DeserializeObject <ChatData>(chatDataStr);
                    chatData.Time = DateTime.Now;//使用服务器时间
                    await SendToWebSocketsAsync(_sockets.Where(t => t != socket).ToList(), chatData);
                }
                catch (Exception ex)
                {
                    Log(ex.Message);
                    _sockets.Remove(socket);//移除
                    chatData = new ChatData()
                    {
                        Info = $"{userName}离开房间。还剩{_sockets.Count}人~~~"
                    };
                    await SendToWebSocketsAsync(_sockets, chatData);

                    //发送关闭 这里很重要 (如果不发送关闭会一直循环,且不能直接break。)
                    await socket.CloseAsync(WebSocketCloseStatus.PolicyViolation, "未知异常 ...", CancellationToken.None);
                }
            }
        }