下载地址:websocket-sharp.dll
这是github上一个mit协议的超高分开源WebSocket库,稳定性非常好,也支持非常多版本,注释详细
下载出来后,用vs2017生成.net4.0的解决方案,就得到dll了
地址:https://github.com/sta/websocket-sharp
命名空间 | 别名 |
WebSocketSharp.Server | wss |
WebSocketSharp.Server | ws |
重启项目,再检查命名空间是否还在
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
函数名: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)
我的help.mdb为代码精灵增加了很多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
If wssv.IsListening Then wssv.Stop() End If
代码很简单,直接看就行了,百度一堆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连接错误") }
wsConnect()
wsSend('xxx')
wsClose()
3.4收到服务器消息
//连接接收信息后触发的事件,自己再改写 function wsOnMessage(msg) { console.log('收到消息:' + msg.data) }
类似的还有 连接成功后事件wsOnOpen、连接断开后事件wsOnClose、连接错误后事件wsOnError
Functions.Execute("WsSendOne",ID,"xxx")
Functions.Execute("WsSendAll","xxx")
Functions.Execute("WsSendAll","xxx")
Functions.Execute("WsKickOff",用户ID)
在WsReceivedMessage维护
类似的还有 用户登录后WsUserLogged、用户退出后WsUserLogout、ws异常触发事件WsOnError
注意一下用户登录后WsUserLogged能获取携带的参数哦,需要前面前端的配合
'通过 cqs("token")来获取value值,注意区分大小写,注意是否为Nothing Dim cqs As System.Collections.Specialized.NameValueCollection = Args(2)
ws是持久实时连接,并不会发送心跳包,要心跳就自行实现
页面刷新,ws会立刻断开,自行解决重连
ws也是http,只不过头部增加了升级标志而已。用宝塔的反向代理,添加后要自行修改代码
如果是直连狐表,是不会断的
如果只通过nginx反向代理,默认情况下1分钟会断,因为nginx有个设置,默认是超过60秒无请求就断开
前端还要做个心跳,9分钟的时候发一下。服务器是否回复都没所谓。
可能是技术不够,网上也没看到什么前置拦截方法。网上说也是连接后检查ID,然后立刻踢出
例如http监听了80,那你就要用非80,例如81
如果想集成到http里,只能官方改自己的HttpServer源码,集成进去才行,我们是第三方外挂的。
那这样会不方便吗?我服务器要开2个端口?其实不用,现在都是用Nginx反向代理的啦,对外统一一个80或者443,内部想怎么反向都可以
而且我也更加推荐,专人专事,更加稳定易用