狐表bs集成websocket方法,dll来源于github 3.5k高分数的C# Websocket库 稳定性和兼容性非常好

发表日期: 2020-10-28

1基础引入

1.1引入dll

下载地址:websocket-sharp.dll

这是github上一个mit协议的超高分开源WebSocket库,稳定性非常好,也支持非常多版本,注释详细

下载出来后,用vs2017生成.net4.0的解决方案,就得到dll了

地址:https://github.com/sta/websocket-sharp

1.2添加2个命名空间

命名空间别名
WebSocketSharp.Serverwss
WebSocketSharp.Serverws

重启项目,再检查命名空间是否还在

1.3添加全局代码

Public wssv As New wss.WebSocketServer() 'WebSocket容器
Public wssh As Object '将来挂载进去WebSocket容器的实例

'Websocket的实例代码
Public Class WsChat
    Inherits wss.WebSocketBehavior

    '默认构造函数
    Public Sub New()
    End Sub

    '1重写客户端上线后的事件
    Protected Overrides Sub OnOpen() 
        Functions.Execute("WsUserLogged",Id,Context.Origin,Context.QueryString)
    End Sub

    '2重写收到客户端下线的事件
    Protected Overrides Sub OnClose(ByVal e As ws.CloseEventArgs) 
        Functions.Execute("WsUserLogout",Id)
    End Sub 

    '3重写收到客户端消息后的事件
    Protected Overrides Sub OnMessage(ByVal e As ws.MessageEventArgs) 
        Functions.Execute("WsReceivedMessage",Id,e.Data)
    End Sub

    '4重写报错异常事件
    Protected Overrides Sub OnError(ByVal e As ws.ErrorEventArgs) 
        Functions.Execute("WsOnError",e.Message)
    End Sub

End Class

1.4添加内部函数

函数名:WsKickOff

'踢某个ID的用户下线
'小技巧 wshh.Sessions.Ids是所有在线用户的ID集合,可以用来Count或者判断Contains

'通过Functions.Execute("WsKickOff",ID)使用

Dim ID As String =Args(0)

If wssh.Sessions.Ids.Contains(ID) Then 
    wssh.Sessions.CloseSession(ID)
End If


函数名:WsSendAll

'群发消息,Ele的type类型有4种:success,warning,info,error
'通过Functions.Execute("WsSendAll","xxx")使用

Dim s1 As String = Args(0)
wssv.WebSocketServices.Broadcast(s1)


函数名:WsSendOne

'对某个ID的用户发送文本消息。Ele的type类型有4种:success,warning,info,error
'小技巧 wshh.Sessions.Ids是所有在线用户的ID集合,可以用来Count或者判断Contains

'通过Functions.Execute("WsSendOne",ID,"xxx")使用

Dim ID As String = Args(0)
Dim s1 As String = Args(1)

If wssh.Sessions.Ids.Contains(ID) Then    
    wssh.Sessions.SendTo(s1,ID)
End If


函数名:WsOnError

'当WebSocket服务器端异常报错的事件
Dim msg As String =Args(0)


函数名:WsReceivedMessage

'收到WebSocket客户端消息后的事件

Dim ID As String =Args(0)
Dim msg As String =Args(1)


函数名:WsUserLogged

'WebSocket客户端上线后的事件,知道登陆用户的ID,和其他数据
Dim ID As String =Args(0)
Dim Origin As String = Args(1) '客户端请求地址
Dim cqs As System.Collections.Specialized.NameValueCollection = Args(2) '通过 cqs("token")来获取value值,注意区分大小写,注意是否为Nothing


函数名:WsUserLogout

'WebSocket客户端下线后的事件,知道下线用户的ID
Dim ID As String =Args(0)

1.5更新代码精灵

我的help.mdb为代码精灵增加了很多websocket的提示

help.mdb下载

2开始使用

2.1狐表启动WebSocket

wssv = New wss.WebSocketServer("ws://127.0.0.1:9091")
wssv.AddWebSocketService(Of WsChat)("/WsChat")
'尝试启动
Try
    wssv.Start()

    '把ws实例放进去全局变量,方便使用
    Dim lwh As List(of wss.WebSocketServiceHost) = wssv.WebSocketServices.Hosts
    For Each wh As wss.WebSocketServiceHost In lwh
        If wh.Path="/WsChat" Then
            wssh = wh
            Exit For
        End If
    Next    
Catch ex As Exception
    Messagebox.Show("Websocket启动失败:" & ex.Message)
End Try

2.2狐表停止WebSocket

If  wssv.IsListening Then
    wssv.Stop()
End If

2.3前端代码

代码很简单,直接看就行了,百度一堆h5关于websocket的使用,都是这些方法

let ws = null

//方法:
//主动创建ws连接
function wsConnect() {
    if (typeof(WebSocket) === "undefined") {
        console.log('您的浏览器不支持WebSocket')
    } else {

        if (!ws || ws.readyState == 0 || ws.readyState == 3) {
            //根据开发环境配置path,注意是否支持https,决定这里是ws还是wss,否则会被nginx拦截
            let path = 'ws://127.0.0.1:9091'
            //如果要携带参数,可以 ws://127.0.0.1:9091?token=aaa123 我在狐表后端有说接收方法

            // 实例化socket
            ws = new WebSocket(path)
            // 重写socket连接的方法
            ws.onopen = wsOnOpen
            // 重写socket监听错误消息的方法
            ws.onerror = wsOnError
            // 重写socket接收消息的方法
            ws.onmessage = wsOnMessage
            // 重写socket关闭的方法
            ws.onclose = wsOnClose
        }
    }
}

//主动向服务器发送文本
function wsSend(msg) {
    ws.send(msg)
}

//主动关闭连接
function wsClose() {
    if (ws) {
        ws.close()
        console.log("ws主动关闭连接")
    }
}

//事件:
//连接成功后触发的事件
function wsOnOpen() {
    console.log("ws连接成功后")
}

//连接接收信息后触发的事件
function wsOnMessage(msg) {
    console.log('收到消息:' + msg.data)
}

//连接关闭后触发的事件
function wsOnClose() {
    console.log("ws关闭连接后")
}

//WS报错后触发的事件
function wsOnError() {
    console.log("ws连接错误")
}

3前端功能

3.1主动连接服务器

wsConnect()

3.2发送消息

wsSend('xxx')

3.3主动断开连接

wsClose()

3.4收到服务器消息

//连接接收信息后触发的事件,自己再改写
function wsOnMessage(msg) {
    console.log('收到消息:' + msg.data)
}

类似的还有 连接成功后事件wsOnOpen、连接断开后事件wsOnClose、连接错误后事件wsOnError

4后端功能

4.1对某个用户发消息

Functions.Execute("WsSendOne",ID,"xxx")

4.2群发消息

Functions.Execute("WsSendAll","xxx")

4.3群发消息

Functions.Execute("WsSendAll","xxx")

4.4踢人下线

Functions.Execute("WsKickOff",用户ID)

4.5收到消息

在WsReceivedMessage维护

类似的还有 用户登录后WsUserLogged、用户退出后WsUserLogout、ws异常触发事件WsOnError

注意一下用户登录后WsUserLogged能获取携带的参数哦,需要前面前端的配合

'通过 cqs("token")来获取value值,注意区分大小写,注意是否为Nothing
Dim cqs As System.Collections.Specialized.NameValueCollection = Args(2)

5注意的坑

5.1ws没有心跳

ws是持久实时连接,并不会发送心跳包,要心跳就自行实现

5.2在页面刷新后ws会断开

页面刷新,ws会立刻断开,自行解决重连

5.3nginx反向代理

ws也是http,只不过头部增加了升级标志而已。用宝塔的反向代理,添加后要自行修改代码

5.4保持不掉线

5.5没有连接前拦截

可能是技术不够,网上也没看到什么前置拦截方法。网上说也是连接后检查ID,然后立刻踢出

5.6不能与HttpServer共用同一个端口



随便看看

Copyright © 2016-2022 江门蓬江区华越科技公司 版权所有 | 承接软件定制开发,欢迎联系
粤ICP备17073215号