JavaScript WebSocket C# SuperSocket.WebSocket 示例


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);
};