HTML5 WebSocket
ASP.NET Core 中的 WebSocket 支持
WS: WebSocket
WSS: WebSocket Secure
WS是非安全的,WSS是安全的。非安全的没有证书,安全的需要SSL证书。
WS的体现形式是TCP + WS AS WS ,WSS的体现形式是TCP + TLS + WS AS WSS。
WS一般默认是80端口,而WSS默认是443端口,大多数网站用的就是80和433端口。
http协议下使用ws,https协议下使用wss。
webSocket = new WebSocket("ws://localhost:port/hub");
webSocket = new WebSocket("wss://localhost:port/hub");
一、WebSocket
WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议
● 支持双向通信,实时性更强
● 可以发送文本,也可以发送二进制数据
● 减少通信量:只要建立起WebSocket连接,就希望一直保持连接状态。和HTTP相比,不但每次连接时的总开销减少,而且由于WebSocket的首部信息很小,通信量也相应减少了
二、双向通信
HTTP 协议有一个缺陷:通信只能由客户端发起。举例来说,我们想了解今天的天气,只能是客户端向服务器发出请求,服务器返回查询结果。HTTP 协议做不到服务器主动向客户端推送信息。这种单向请求的特点,注定了如果服务器有连续的状态变化,客户端要获知就非常麻烦。
在WebSocket协议之前,有三种双向通信的方式:轮询(polling)、长轮询(long-polling)和iframe流(streaming)。
1、轮询(polling)
轮询是客户端和服务器之间会一直进行连接,每隔一段时间就询问一次。其缺点也很明显:连接数会很多,一个接受,一个发送。而且每次发送请求都会有Http的Header,会很耗流量,也会消耗CPU的利用率。
● 优点:实现简单,无需做过多的更改
● 缺点:轮询的间隔过长,会导致用户不能及时接收到更新的数据;轮询的间隔过短,会导致查询请求过多,增加服务器端的负担
2、长轮询(long-polling)
长轮询是对轮询的改进版,客户端发送HTTP给服务器之后,看有没有新消息,如果没有新消息,就一直等待。当有新消息的时候,才会返回给客户端
● 优点:比 Polling 做了优化,有较好的时效性
● 缺点:保持连接会消耗资源; 服务器没有返回有效数据,程序超时。
3、iframe流(streaming)
iframe流方式是在页面中插入一个隐藏的iframe,利用其src属性在服务器和客户端之间创建一条长连接,服务器向iframe传输数据(通常是HTML,内有负责插入信息的javascript),来实时更新页面。
● 优点:消息能够实时到达;浏览器兼容好
● 缺点:服务器维护一个长连接会增加开销;IE、chrome、Firefox会显示加载没有完成,图标会不停旋转。
三、Socket
Socket 是一个网络通信的套接字(接口);分为 服务端 和 客户端;使用 TCP/IP协议 或 UDP 协议;
服务端
private void Start_Click(object sender, EventArgs e)
{try{var _ip = txtIP.Text;var _port = txtPort.Text;Validate(_ip, _port);socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);socketSend = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);IPAddress ip = IPAddress.Parse(_ip);//将IP地址和端口号绑定到网络节点endpoint上 //IPEndPoint point = new IPEndPoint(ip, Convert.ToInt32(_port));IPEndPoint point = new IPEndPoint(IPAddress.Any, Convert.ToInt32(_port));//自动获取ip可使用此方法socketWatch.Bind(point);ShowMsg("开始监听 ");LogUtils.GetInstance().Info("");//设置监听 - 将套接字的监听队列长度限制为10socketWatch.Listen(10);ShowMsg("开始监听 ");LogUtils.GetInstance().Info("");Thread thread = new Thread(Listen);thread.IsBackground = true;thread.Start();Start.Enabled = false;btnStop.Enabled = true;ShowMsg("开始监听客户端传来的信息 ");}catch (Exception ex){MessageBox.Show("启动服务失败,请联系管理员!");LogUtils.GetInstance().Error(ex.Message);}
}
客户端
using CoreLibrary;
using CoreLibrary.UMeeting;
using Lawyer.Api.RequestModel;
using Lawyer.Entity;
using Newtonsoft.Json;
using System;
using System.Configuration;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Web.Mvc;namespace Lawyer.Api.Controllers
{public class DefaultController : Controller{log4net.ILog logger = log4net.LogManager.GetLogger(typeof(ConferenceController));string ClassName = string.Empty;string MaxCallTime = string.Empty;ManualResetEvent connectDone = new ManualResetEvent(false);ManualResetEvent sendDone = new ManualResetEvent(false);ManualResetEvent receiveDone = new ManualResetEvent(false);String response = String.Empty;Socket tcpClient = null;public DefaultController(){ClassName = "Api.Controllers.ConferenceController";MaxCallTime = StringPlus.GetWebConfigKey("UMMaxCallTime");IPAddress ipaddress = IPAddress.Parse("101.201.44.11");EndPoint point = new IPEndPoint(ipaddress, 8803);tcpClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);tcpClient.BeginConnect(point, new AsyncCallback(ConnectCallback), tcpClient);//建立连接 connectDone.WaitOne();string sendMsg = "{"key":"verify","command":9,"userid":"8888888","password":"8888888888"}";Send(tcpClient, sendMsg, 9);sendDone.WaitOne();}/// <summary>/// 双向回呼/// </summary>/// <param name="data"></param>/// <returns></returns>[HttpPost]public ActionResult CallBack(string conferenceid){try{Thread thread = new Thread(new ParameterizedThreadStart(Monitor));thread.IsBackground = true;thread.Start(conferenceid);return ResultJsonMessage.Tool.SuccessResult();}catch (Exception ex){logger.Info("Entered CallBack() " + ex.Message);return ResultJsonMessage.Tool.ExceptionResult(ex);}}/// <summary>/// 修改订单状态/// </summary>void UpdateOrder(object conferenceid){try{logger.Info("Entered UpdateOrder 开始订单修改操作");OrderCallback o = biz.GetModelByCallSid(conferenceid.ToString());if (o != null){logger.Info("Entered UpdateOrder 执行业务逻辑");}}catch (Exception ex){logger.Info("Entered UpdateOrder(" + conferenceid.ToString() + ") " + ex.Message);}}/// <summary>/// 监听会议/// </summary>/// <param name="conferenceid"></param>void Monitor(object conferenceid){string monitor = "{"key":"" + conferenceid + "","command":13,"regphoneid":"" + ConfigurationManager.AppSettings["UMregphoneid"] + "","conferenceid":"" + conferenceid + ""}";Send(tcpClient, monitor, 13);sendDone.WaitOne();Receive(tcpClient);receiveDone.WaitOne();}private void ConnectCallback(IAsyncResult ar){try{// Retrieve the socket from the state object. Socket client = (Socket)ar.AsyncState;// Complete the connection. client.EndConnect(ar);///Console.WriteLine("Socket connected to {0}", client.RemoteEndPoint.ToString());logger.Info(string.Format("Socket connected to {0}", client.RemoteEndPoint.ToString()));// Signal that the connection has been made. connectDone.Set();}catch (Exception e){//Console.WriteLine(e.ToString());logger.Info("ConnectCallback Exception Ln 304" + e.ToString());}}private void Send(Socket client, String data, int type){// Convert the string data to byte data using ASCII encoding. byte[] byteData = Encoding.UTF8.GetBytes(data);#regionbyte[] abuff = new byte[4];byte[] bbuff = new byte[1];ConvertIntToByteArray(data.Length + abuff.Length + bbuff.Length, ref abuff);ConvertIntToByte(type, ref bbuff);byte[] d = new byte[2048];abuff.CopyTo(d, 0);bbuff.CopyTo(d, abuff.Length);byteData.CopyTo(d, abuff.Length + bbuff.Length);int dlength = byteData.Length + 5;#endregion client.BeginSend(d, 0, dlength, 0, new AsyncCallback(SendCallback), client);}private void SendCallback(IAsyncResult ar){try{// Retrieve the socket from the state object. Socket client = (Socket)ar.AsyncState;// Complete sending the data to the remote device. int bytesSent = client.EndSend(ar);//Console.WriteLine("Sent {0} bytes to server.", bytesSent);logger.Info("SendCallback " + string.Format("Sent {0} bytes to server.", bytesSent));// Signal that all bytes have been sent. sendDone.Set();}catch (Exception e){logger.Info("SendCallback Exception Ln 347 " + e.ToString());}}private void Receive(Socket client){try{// Create the state object. StateObject state = new StateObject();state.workSocket = client;// Begin receiving the data from the remote device. client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);}catch (Exception e){//Console.WriteLine(e.ToString());logger.Info("Receive Exception Ln 364 " + e.ToString());}}private void ReceiveCallback(IAsyncResult ar){//logger.Info("Entered ReceiveCallback Begin Ln 370");try{// Retrieve the state object and the client socket // from the asynchronous state object. StateObject state = (StateObject)ar.AsyncState;Socket client = state.workSocket;// Read data from the remote device. int bytesRead = client.EndReceive(ar);if (bytesRead > 0){// There might be more data, so store the data received so far.state.sb.Append(Encoding.UTF8.GetString(state.buffer, 0, bytesRead));//int headerLen = BitConverter.ToInt32(state.buffer.Take(4).ToArray(), 0);//logger.Info("Entered header长度 " + headerLen);string log = "";if (bytesRead > 5){log = Encoding.UTF8.GetString(state.buffer, 5, bytesRead);}else{log = Encoding.UTF8.GetString(state.buffer, 0, bytesRead);}if (bytesRead > 50){ConvertObj(log);}//log = log.Substring(0, log.LastIndexOf("}") + 1);//logger.Info("Entered Ln 400 " + log);// Get the rest of the data. client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);}else{// All the data has arrived; put it in response. if (state.sb.Length > 1){response = state.sb.ToString();logger.Info("Entered response Ln 410 " + response);}// Signal that all bytes have been received. receiveDone.Set();}//logger.Info("Entered state.sb Ln 415 " + state.sb.ToString());}catch (Exception e){//Console.WriteLine(e.ToString());logger.Info("ReceiveCallback Exception Ln 420 " + e.ToString());}//logger.Info("Entered ReceiveCallback End Ln 422");}bool ConvertIntToByteArray(Int32 m, ref byte[] arry){if (arry == null) return false;if (arry.Length < 4) return false;arry[0] = (byte)(m & 0xFF);arry[1] = (byte)((m & 0xFF00) >> 8);arry[2] = (byte)((m & 0xFF0000) >> 16);arry[3] = (byte)((m >> 24) & 0xFF);return true;}bool ConvertIntToByte(Int32 m, ref byte[] arry){if (arry == null) return false;arry[0] = (byte)(m & 0xFF);return true;}void ConvertObj(string log){logger.Info("Entered ConvertObj Begin");logger.Info("Entered 原始字符串 " + log);try{string first = log.Substring(0, 1);string last = log.Substring(log.Length - 1, 1);if (first == "{" && last != "}"){logger.Info("Entered 字符串截取操作 Ln 457 " + log);log = log.Substring(0, log.LastIndexOf("}") + 1);}UMPushInfo umPush = (UMPushInfo)JsonConvert.DeserializeObject(log, typeof(UMPushInfo));if (umPushmand == 15 && umPush.phonelist != null){logger.Info("Entered phonelist总数:" + umPush.phonelist.Count.ToString());if (umPush.phonelist[0].callstate == 2 || umPush.phonelist[0].callstate == 3){//logger.Info("Entered 15 " + umPush.phonelist[0].callstate);//logger.Info("Entered 结束会议");//string command = "{"key":"","command":12,"client":"","conferenceid":"" + ferenceid + "","commandno ":9,"memberid":0,"address":"","phone":""}";//Send(tcpClient, command, 12);}}if (umPushmand == 15 && umPush.phonelist[0].callstate == 0){logger.Info("Entered 15 0 呼叫中");}if (umPushmand == 15 && umPush.phonelist[0].callstate == 1 && umPush.phonelist[0].role == 0){logger.Info("Entered 15 1 主持人接通");}if (umPushmand == 15 && umPush.phonelist[0].callstate == 1 && umPush.phonelist[0].role == 3){logger.Info("Entered 15 1 参会人接通");Thread thread = new Thread(new ParameterizedThreadStart(UpdateOrder));thread.IsBackground = true;thread.ferenceid);}if (umPushmand == 15 && umPush.phonelist[0].callstate == 2){logger.Info("Entered 15 2 未接通");}if (umPushmand == 15 && umPush.phonelist[0].callstate == 3){logger.Info("Entered 15 3 挂断");}if (umPushmand == 18 && ferencestate == 0){logger.Info("Entered 18 0 会议还未开始");}if (umPushmand == 18 && ferencestate == 1){logger.Info("Entered 18 1 会议正在召开");}if (umPushmand == 18 && ferencestate == 2){logger.Info("Entered 18 2 会议成功关闭");}}catch (Exception ex){logger.Info("Entered Exception Ln 504 " + ex.Message);logger.Info("Entered " + log);}logger.Info("Entered ConvertObj End");}}
}
*
*
*
*
*
本文发布于:2024-01-28 00:14:44,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/17063720833497.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |