bklLiudl
2024-07-23 675b8bcc4a3630d95e3d0b97d933e63442075ecb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.WebSockets;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Threading;
using System.Web;
using System.Web.Http;
using System.Web.WebSockets;
using Common;
using Model;
using Model.MessageModel;
 
namespace wms.Controllers
{
    [RoutePrefix("api/WSChat")]
    public class WSChatController : ApiController
    {
        private static List<WebSocket> _socket = new List<WebSocket>();
 
        [HttpGet]
        [Route("Get")]
        public HttpResponseMessage Get()
        {
            //if (HttpContext.Current.IsWebSocketRequest)
            //{
            //    HttpContext.Current.AcceptWebSocketRequest(ProcessWSChat);
            //}
            //return new HttpResponseMessage(HttpStatusCode.SwitchingProtocols);
 
            //在服务端接受web socket请求,传入的函数作为web socket的处理函数,待web socket建立后该函数会被调用,
            //在该函数中可以对web socket进行消息收发
            HttpContext.Current.AcceptWebSocketRequest(ProcessRequest);
            //构造同意切换至web socket的response
            return Request.CreateResponse(HttpStatusCode.SwitchingProtocols);
        }
 
        private async System.Threading.Tasks.Task ProcessRequest(AspNetWebSocketContext context)
        {
            var socket = context.WebSocket;//传入的context中当前的web socket对象
            _socket.Add(socket);//此处将web socket对象加入一个静态列表中
 
            //进入一个无限循环,当web socket close是循环结束
            while (true)
            {
                var buffer = new ArraySegment<byte>(new byte[1024]);
                var receviedResult = await socket.ReceiveAsync(buffer, CancellationToken.None);//对web socket进行异步接收数据
                if (receviedResult.MessageType == WebSocketMessageType.Close)
                {
                    await socket.CloseAsync(WebSocketCloseStatus.Empty, string.Empty, CancellationToken.None);//如果client发起close请求,对client进行ack
                    _socket.Remove(socket);
                    break;
                }
 
                if (socket.State == WebSocketState.Open)
                {
                    string recvMsg = Encoding.UTF8.GetString(buffer.Array, 0, receviedResult.Count);
                    var recvBytes = Encoding.UTF8.GetBytes(recvMsg);
                    var sendBuffer = new ArraySegment<byte>(recvBytes);
                    foreach (var innerSocket in _socket)//当接收到文本消息时,对当前服务器上所有web socket链接进行广播
                    {
                        if (innerSocket == socket)
                        {
                            await innerSocket.SendAsync(sendBuffer, WebSocketMessageType.Text, true, CancellationToken.None);
                        }
                    }
                }
            }
        }
 
        /// <summary>
        /// 文字发送
        /// </summary>
        /// <param name="AlarmText"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("AlarmInformation")]
        public string AlarmInformation(string AlarmText)
        { 
            SendMsg(AlarmText);
            return "成功!";
        }
 
        /// <summary>
        /// 模型发送
        /// </summary>
        /// <param name="AlarmText"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("AlarmInformationList")]
        public string AlarmInformationModel(DeviceMessage AlarmText)
        {
            SendMsg(AlarmText);
            return "成功!";
        }
 
        [HttpPost]
        [Route("ShuaXIn")]
        public string ShuaXIn(string AlarmText)
        {
            SendMsg(AlarmText);
            return "成功!";
        }
 
        private readonly ClientWebSocket webSocket = new ClientWebSocket();
        private readonly CancellationToken _cancellation = new CancellationToken();
        ///客户端发送消息
        private void SendMsg(object data)
        {
            try
            {
                var a = data.ToString();
                //webSocket.ConnectAsync(new Uri("ws://localhost:57061/api/WSChat"), _cancellation);
                //var sendBytes = ObjectToBytes(data);//发送的数据
                var recvBytes = Encoding.UTF8.GetBytes(data.ToString());
                var bsend = new ArraySegment<byte>(recvBytes);
                foreach (var innerSocket in _socket)//当接收到文本消息时,对当前服务器上所有web socket链接进行广播
                {
 
                    innerSocket.SendAsync(bsend, WebSocketMessageType.Text, true, CancellationToken.None);
                    //innerSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "1", CancellationToken.None);
                    //innerSocket.Dispose();//记得一定要释放不然服务端还产生很多连接
                }
                
                
            }
            catch (Exception ex)
            {
                //logger.Error(ex.Message);//lognet4日志记录
            }
        }
 
        private byte[] ObjectToBytes(object obj)
        {
            BinaryFormatter se = new BinaryFormatter();
            MemoryStream memStream = new MemoryStream();
            se.Serialize(memStream, obj);
            byte[] bobj = memStream.ToArray();
            memStream.Close();
            return bobj;
 
        }
        //public abstract System.Threading.Tasks.Task SendAsync(ArraySegment<byte> buffer, WebSocketMessageType messageType, bool endOfMessage, CancellationToken cancellationToken);
    }
}