C# WebSocket 后端代码:
using Newtonsoft.Json; using SuperSocket.WebSocket; using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; namespace WebSocketServerHost { public partial class Form1 : Form { private WebSocketServer _server; private ConcurrentDictionary<string, WebSocketSession> _sessionList = new ConcurrentDictionary<string, WebSocketSession>(); private double _currentSpeed = 10; public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { try { _server = new WebSocketServer(); _server.NewSessionConnected += server_NewSessionConnected; _server.NewMessageReceived += server_NewMessageReceived; _server.SessionClosed += server_SessionClosed; _server.Setup("127.0.0.1", 40001); _server.Start(); Log("WebSocket服务端启动成功"); } catch (Exception ex) { Log("WebSocket服务端启动失败:" + ex.Message); } } #region Log private void Log(string log) { if (!this.IsDisposed) { if (this.InvokeRequired) { this.BeginInvoke(new Action(() => { textBox1.AppendText(DateTime.Now.ToString("HH:mm:ss.fff") + " " + log + "\r\n\r\n"); })); } else { textBox1.AppendText(DateTime.Now.ToString("HH:mm:ss.fff") + " " + log + "\r\n\r\n"); } } } private void ClearLog() { if (!this.IsDisposed) { if (this.InvokeRequired) { this.BeginInvoke(new Action(() => { textBox1.Text = string.Empty; })); } else { textBox1.Text = string.Empty; } } } #endregion #region WebSocketServer 事件 private void server_SessionClosed(WebSocketSession session, SuperSocket.SocketBase.CloseReason value) { try { Log("WebSocket客户端关闭 SessionID=" + session.SessionID); WebSocketSession temp; _sessionList.TryRemove(session.SessionID, out temp); } catch (Exception ex) { Log("server_SessionClosed 错误" + ex.Message); } } private void server_NewMessageReceived(WebSocketSession session, string value) { try { int maxLength = 30; if (value.Length > maxLength) value = value.Substring(0, maxLength); Log("WebSocket收到客户端消息 SessionID=" + session.SessionID + " value=" + value); } catch (Exception ex) { Log("server_NewMessageReceived 错误" + ex.Message); } } private void server_NewSessionConnected(WebSocketSession session) { try { Log("WebSocket客户端连接 SessionID=" + session.SessionID); _sessionList.TryAdd(session.SessionID, session); } catch (Exception ex) { Log("server_NewSessionConnected 错误" + ex.Message); } } #endregion //启动 private void button1_Click(object sender, EventArgs e) { SocketData data = new SocketData(); data.type = 1; data.speed = _currentSpeed; Log("启动 speed=" + _currentSpeed.ToString("0")); Broadcast(data); } //停止 private void button2_Click(object sender, EventArgs e) { Log("停止"); SocketData data = new SocketData(); data.type = 2; Broadcast(data); } //位置1 private void button3_Click(object sender, EventArgs e) { SocketData data = new SocketData(); data.direction = 0; data.index = 0; data.type = 3; data.speed = _currentSpeed; data.startDeltaX = 20; data.startDeltaZ = 0; Log("位置2 direction=" + data.direction + " index=" + data.index + " speed=" + _currentSpeed.ToString("0")); Broadcast(data); } //位置2 private void button4_Click(object sender, EventArgs e) { SocketData data = new SocketData(); data.direction = 1; data.index = 38; data.type = 3; data.speed = _currentSpeed; data.startDeltaX = 40; data.startDeltaZ = 0; Log("位置2 direction=" + data.direction + " index=" + data.index + " speed=" + _currentSpeed.ToString("0")); Broadcast(data); } //清空日志 private void button5_Click(object sender, EventArgs e) { ClearLog(); } //加速 private void button6_Click(object sender, EventArgs e) { Task.Run(() => { _currentSpeed *= 1.3; if (_currentSpeed > 3000) _currentSpeed = 3000; Log("加速 speed=" + _currentSpeed.ToString("0")); SocketData data = new SocketData(); data.type = 2; Broadcast(data); Thread.Sleep(10); data = new SocketData(); data.type = 1; data.speed = _currentSpeed; Broadcast(data); }); } //减速 private void button7_Click(object sender, EventArgs e) { Task.Run(() => { _currentSpeed *= 0.7; if (_currentSpeed < 10) _currentSpeed = 10; Log("减速 speed=" + _currentSpeed.ToString("0")); SocketData data = new SocketData(); data.type = 2; Broadcast(data); Thread.Sleep(10); data = new SocketData(); data.type = 1; data.speed = _currentSpeed; Broadcast(data); }); } private void Broadcast(SocketData data) { _server.Broadcast(_sessionList.Values.ToList(), JsonConvert.SerializeObject(data), null); } } }
JavaScript WebSocket 前端代码:
实现了断线重连
startWebSocket() { let websocket = new WebSocket(websocket_address); websocket.onopen = e => { console.log('WebSocket Open'); }; websocket.onclose = e => { setTimeout(() => { this.startWebSocket(); }, 5000); console.log('WebSocket Close'); }; websocket.onmessage = e => { console.log('WebSocket Message ' + e.data); let data = eval('(' + e.data + ')'); if (data.type == 1) { this.continue(data.speed); } else if (data.type == 2) { this.suspend(); } else if (data.type == 3) { this.stop(); this.startDeltaX = data.startDeltaX; this.startDeltaZ = data.startDeltaZ; this.start(data.index, data.direction, data.speed); } }; websocket.onerror = e => { websocket.onclose = function () { } websocket.close(); setTimeout(() => { this.startWebSocket(); }, 5000); console.error(e); }; }
如何正确关闭WebSocket:
websocket.onerror = e => { websocket.onclose = function () { } websocket.close(); setTimeout(() => { this.startWebSocket(); }, 5000); console.error(e); };