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 _socket = new List(); [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(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(recvBytes); foreach (var innerSocket in _socket)//当接收到文本消息时,对当前服务器上所有web socket链接进行广播 { if (innerSocket == socket) { await innerSocket.SendAsync(sendBuffer, WebSocketMessageType.Text, true, CancellationToken.None); } } } } } /// /// 文字发送 /// /// /// [HttpPost] [Route("AlarmInformation")] public string AlarmInformation(string AlarmText) { SendMsg(AlarmText); return "成功!"; } /// /// 模型发送 /// /// /// [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(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 buffer, WebSocketMessageType messageType, bool endOfMessage, CancellationToken cancellationToken); } }