本篇文章是基于BestHttp插件实现的websocket,大家可以搜索这个插件进行学习使用。
websocket是为了克服http无法双向通信而引入的,在通常的使用中,可以复用http的端口与功能,除此外,他们没有其他的联系,而是完全是独立的协议,通常情况下,http是单向的web 服务,而websocket是全双工的,服务器和客户端可以实时的传输信息,在引用时他们可以在http服务器上同时部署。
在弱网环境下,发送消息无法抵达接收端;抑或,断网到浏览器约定时限等一些异常情况都会触发onclose和onerror,所以理论上,我们只要在onclose和onerror时,重新创建长连接就可以。
思路
弱网、断连所导致重连都是被动的,而在一般的websocket连接中都是存在心跳机制的,客户端和服务端约定一个特定的心跳消息用于检测链路是否通信正常。
我们通过心跳机制,在客户端来检测链路的正常,在约定时间间隔内收不到心跳或者其他任何通信消息时,客户端进行主动重连。当连接成功时,开启心跳;在收到消息时,重置心跳并开启下一轮检测,所以我们只需要在onopen和onmessage中加入心跳检测就行。
code:
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159using System.Collections; using System.Collections.Generic; using UnityEngine; using BestHTTP; using BestHTTP.WebSocket; using BestHTTP.Examples; using System; public class WebSocketModel : MonoBehaviour { string address; WebSocket webSocket; private bool lockReconnect = false; private Coroutine _pingCor,_clientPing,_serverPing; private void Start() { CreateWebSocket(); } void CreateWebSocket() { try { webSocket = new WebSocket(new System.Uri("ws://8888ws"));//websocket访问地址 InitHandle(); webSocket.Open(); } catch(Exception e) { Debug.Log("websocket连接异常:" + e.Message); ReConnect(); } } void InitHandle() { RemoveHandle(); webSocket.OnOpen += OnOpen; webSocket.OnMessage += OnMessageReceived; webSocket.OnClosed += OnClosed; webSocket.OnError += OnError; } void RemoveHandle() { webSocket.OnOpen -= OnOpen; webSocket.OnMessage -= OnMessageReceived; webSocket.OnClosed -= OnClosed; webSocket.OnError -= OnError; } void OnOpen(WebSocket ws) { Debug.Log("websocket连接成功"); if(_pingCor!=null) { StopCoroutine(_pingCor); _pingCor = null; } _pingCor = StartCoroutine(HeartPing()); // 心跳检测重置 HeartCheck(); } void OnMessageReceived(WebSocket ws, string message) { // 如果获取到消息,心跳检测重置 // 拿到任何消息都说明当前连接是正常的 HeartCheck(); Debug.Log(message); } void OnClosed(WebSocket ws, UInt16 code, string message) { Debug.Log("websocket关闭," + message); webSocket = null; ReConnect(); } void OnError(WebSocket ws, Exception ex) { if(ex!=null) Debug.Log("websocket连接异常:" + ex.Message); webSocket = null; ReConnect(); } void ReConnect() { if (this.lockReconnect) return; this.lockReconnect = true; StartCoroutine(SetReConnect()); } private IEnumerator SetReConnect() { Debug.Log("正在重连websocket"); yield return new WaitForSeconds(5); CreateWebSocket(); lockReconnect = false; } //心跳检测 private void HeartCheck() { if(_clientPing!=null) { StopCoroutine(_clientPing); _clientPing = null; } if(_serverPing!=null) { StopCoroutine(_serverPing); _serverPing = null; } _clientPing = StartCoroutine(ClientPing()); } // 这里发送一个心跳,后端收到后,返回一个心跳消息 // onmessage拿到返回的心跳就说明连接正常 private IEnumerator ClientPing() { yield return new WaitForSeconds(5); Send("heartbeat"); _serverPing = StartCoroutine(ServerPing()); } // 如果超过一定时间还没重置,说明后端主动断开了 // 如果onclose会执行reconnect,我们执行ws.close()就行了.如果直接执行reconnect 会触发onclose导致重连两次 private IEnumerator ServerPing() { yield return new WaitForSeconds(5); webSocket.Close(); } //发送心跳 private IEnumerator HeartPing() { while(true) { yield return new WaitForSeconds(5); this.Send("heartbeat"); } } //向服务端发送信息 private void Send(string msg) { if (webSocket == null || string.IsNullOrEmpty(msg)) return; if(webSocket.IsOpen) { webSocket.Send(msg); } } }
最后
以上就是高贵指甲油最近收集整理的关于unity websockt断线重连和心跳检测的全部内容,更多相关unity内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复