import IIMHandler from "../interface/i-im-handler"; import ImApi from './../../../apis/im' export default class WebSocketHandlerImp extends IIMHandler { constructor() { super(); this._socket = null this.im_user_id = null this.options = null this.timer = null } register () { return ImApi.register({name: 'xu'}).then(res => { this.im_user_id = res.data.id return res }) } /** * 创建WebSocket连接 * 如:this.imWebSocket = new IMWebSocket(); * this.imWebSocket.createSocket({url: 'ws://10.4.97.87:8001'}); * 如果你使用本地服务器来测试,那么这里的url需要用ws,而不是wss,因为用wss无法成功连接到本地服务器 * @param options 建立连接时需要的配置信息,这里是传入的url,即你的服务端地址,端口号不是必需的。 */ createConnection({options = this.options}) { this._socket = wx.connectSocket({ url: options.url, header: { 'content-type': 'application/json' }, method: 'GET', success: () => { console.log('成功连接') }, fail: () => { console.log('连接失败') } }); this.intervalSendMsg() this.options = options console.log(this.options, 'options') this._onSocketOpen(); this._onSocketMessage(); this._onSocketError(); this._onSocketClose(); } reconnect () { console.log(this.options, 'this.option') this._socket = wx.connectSocket({ url: this.options.url, header: { 'content-type': 'application/json' }, method: 'GET' }); this._onSocketOpen(); this._onSocketMessage(); this._onSocketError(); this._onSocketClose(); console.log('重新连接') } _sendMsgImp({content, success, fail}) { console.log(content, 'content') this._socket.send({ data: JSON.stringify(content), success: () => { success && success({content}); }, fail: (res) => { console.log(res, 'error') if (res.errMsg === 'SocketTask.send:fail SocketTask.readyState is not OPEN') { // 发送消息失败,重新连接socket this.closeConnection() this.createConnection({options: this.options}) } fail && fail(res); } }); } /** * 关闭webSocket */ closeConnection() { console.log('关闭socket') this._socket && this._socket.close(); } _onSocketError(cb) { this._socket.onError((res) => { // this._isLogin = false; this._socket = null console.log('WebSocket连接打开失败,请检查!', res); }) } _onSocketClose(cb) { this._socket.onClose((res) => { // 1分钟无消息后端自动断开连接,code 1006 需要重连socket if (res.code === 1006) { this._socket = wx.connectSocket({ url: this.options.url, success: (res) => { console.log('重连成功', res) }, fail: (err) => { console.log('重连失败', err) } }); return } clearInterval(this.timer) this.timer = null console.log('WebSocket 已关闭!', res) }); } _onSocketOpen() { ImApi.getContacts(getApp().globalData.userinfo.user_id) this._socket.onOpen((res) => { console.log('WebSocket连接已打开!'); }); } /** * webSocket是在这里接收消息的 * 在socket连接成功时,服务器会主动给客户端推送一条消息类型为login的信息,携带了用户的基本信息,如id,头像和昵称。 * 在login信息接收前发送的所有消息,都会被推到msgQueue队列中,在登录成功后会自动重新发送。 * 这里我进行了事件的分发,接收到非login类型的消息,会回调监听函数。 * @private */ _onSocketMessage() { this._socket.onMessage((res) => { console.log(res, 'receive msg') let msg = JSON.parse(res.data); if (msg.type === 'TYPE_ONE') { this._receiveListener.forEach(fn => { fn(msg) }) // this._receiveListener && this._receiveListener(msg); } }) } intervalSendMsg () { this.timer = setInterval(() => { // 定时发消息,免得后端自动断开 this._socket.send({data: JSON.stringify({content: '定时发消息'})}) }, 50000); } }