Bläddra i källkod

消息服务前端websocket整合

nnkwrik 6 år sedan
förälder
incheckning
846083bd87

+ 3 - 1
im-service/src/main/java/io/github/nnkwrik/imservice/constant/MessageType.java

@@ -10,7 +10,9 @@ public class MessageType {
 
     public static final int USER_MESSAGE = 1;
 
-    public static final int ESTABLISH_CHAT = 2;
+    public static final int FIRST_CHAT = 2;
 
     public static final int UNREAD_NUM = 3;
+
+    public static final int ESTABLISH_CHAT = 4;
 }

+ 9 - 12
im-service/src/main/java/io/github/nnkwrik/imservice/controller/ChatController.java

@@ -12,10 +12,7 @@ import io.github.nnkwrik.imservice.service.IndexService;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.format.annotation.DateTimeFormat;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.RequestParam;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.*;
 
 import java.util.Date;
 import java.util.List;
@@ -73,13 +70,13 @@ public class ChatController {
         return Response.ok(vo);
     }
 
-    //把所有未读设为已读, 在退出聊天框时使用
-//    @PostMapping("/chat/flushUnread/{chatId}")
-//    public Response flushUnread(@PathVariable("chatId") int chatId,
-//                                @JWT(required = true) JWTUser user) {
-//        formService.flushUnread(user.getOpenId(), chatId );
-//        log.info("用户openId={}chatId={}的所有未读消息设为已读", user.getOpenId(), chatId);
-//        return Response.ok();
-//    }
+    //把所有未读设为已读, 通过ws实时阅读到消息时
+    @PostMapping("/chat/flushUnread/{chatId}")
+    public Response flushUnread(@PathVariable("chatId") int chatId,
+                                @JWT(required = true) JWTUser user) {
+        formService.flushUnread(chatId ,user.getOpenId());
+        log.info("用户openId={}chatId={}的所有未读消息设为已读", user.getOpenId(), chatId);
+        return Response.ok();
+    }
 
 }

+ 1 - 1
im-service/src/main/java/io/github/nnkwrik/imservice/dao/HistoryMapper.java

@@ -100,7 +100,7 @@ public interface HistoryMapper {
      * @param chat_id
      * @return
      */
-    @Select("select u1_to_u2, message_type, message_body, send_time\n" +
+    @Select("select chat_id,u1_to_u2, message_type, message_body, send_time\n" +
             "from history\n" +
             "where chat_id = #{chat_id} and send_time < #{offset_time,jdbcType=TIMESTAMP} order by send_time desc")
     List<History> getChatHistory(@Param("chat_id") int chatId,@Param("offset_time") Date offsetTime);

+ 2 - 2
im-service/src/main/java/io/github/nnkwrik/imservice/service/FormService.java

@@ -1,7 +1,7 @@
 package io.github.nnkwrik.imservice.service;
 
+import io.github.nnkwrik.imservice.model.po.History;
 import io.github.nnkwrik.imservice.model.vo.ChatForm;
-import io.github.nnkwrik.imservice.model.vo.WsMessage;
 
 import java.util.Date;
 import java.util.List;
@@ -14,5 +14,5 @@ public interface FormService {
 
     ChatForm showForm(int chatId, String userId, int size, Date offsetTime);
 
-//    void addMessageListToSQL(List<WsMessage> messageList);
+    List<History> flushUnread(int chatId, String userId);
 }

+ 4 - 2
im-service/src/main/java/io/github/nnkwrik/imservice/service/impl/FormServiceImpl.java

@@ -74,9 +74,10 @@ public class FormServiceImpl implements FormService {
             chatHistory.addAll(unreadList);
             chatHistory = chatHistory.stream()
                     .filter(a -> offsetTime.compareTo(a.getSendTime()) > 0)
-                    .sorted((a, b) -> a.getSendTime().compareTo(b.getSendTime()))
+                    .sorted((a, b) -> b.getSendTime().compareTo(a.getSendTime()))
                     .limit(size)
                     .collect(Collectors.toList());
+            chatHistory = Lists.reverse(chatHistory);
         }
         vo.setHistoryList(chatHistory);
         if (chatHistory.size() > 1) {
@@ -86,7 +87,8 @@ public class FormServiceImpl implements FormService {
         return vo;
     }
 
-    private List<History> flushUnread(int chatId, String userId) {
+    @Override
+    public List<History> flushUnread(int chatId, String userId) {
         List<WsMessage> unreadMsgList = redisClient.get(chatId + "");
         List<History> unreadHistory = WsListToHisList(unreadMsgList);
         if (unreadHistory != null && unreadHistory.size() > 0 && unreadMsgList.get(0).getReceiverId().equals(userId)) {

+ 5 - 2
im-service/src/main/java/io/github/nnkwrik/imservice/service/impl/IndexServiceImpl.java

@@ -64,9 +64,12 @@ public class IndexServiceImpl implements IndexService {
         List<WsMessage> unread = getDisplayUnread(unreadMessage, unreadCount, size, offsetTime);
         dealUnread(currentUser, unread, unreadCount, resultVoList, chatGoodsMap, chatUserMap);
 
-        List<Integer> unreadChatIds = unread.stream()
-                .map(chat -> chat.getChatId())
+
+        List<Integer> unreadChatIds = unreadMessage.stream()
+                .filter(unreadList -> unreadList != null && unreadList.size() > 0)
+                .map(unreadList -> unreadList.get((0)).getChatId())
                 .collect(Collectors.toList());
+
         PageHelper.offsetPage(0, size);
         List<HistoryExample> read = historyMapper.getLastReadChat(unreadChatIds, currentUser, offsetTime);
         dealRead(read, currentUser, resultVoList, chatGoodsMap, chatUserMap);

+ 1 - 3
im-service/src/main/java/io/github/nnkwrik/imservice/service/impl/WebSocketServiceImpl.java

@@ -37,8 +37,6 @@ public class WebSocketServiceImpl implements WebSocketService {
     @Autowired
     private RedisClient redisClient;
 
-    @Autowired
-    private FormService formService;
 
     @Override
     public int getUnreadCount(String userId) {
@@ -85,7 +83,7 @@ public class WebSocketServiceImpl implements WebSocketService {
             return;
         }
 
-        if (message.getMessageType() == MessageType.ESTABLISH_CHAT) {
+        if (message.getMessageType() == MessageType.FIRST_CHAT) {
             //首次发送,设为双方可见
             chatMapper.showToBoth(message.getChatId());
         }

+ 57 - 47
wx-front/app.js

@@ -1,6 +1,7 @@
 var util = require('./utils/util.js');
 var api = require('./config/api.js');
 var user = require('./services/user.js');
+var websocket = require('./services/websocket.js');
 
 var SocketTask
 
@@ -18,56 +19,61 @@ App({
       console.log('app login')
       this.globalData.userInfo = wx.getStorageSync('userInfo');
       this.globalData.token = wx.getStorageSync('token');
-      this.socketTask();
-      this.wsConnect();
+      
+      websocket.wsConnect()
+      
     }).catch(() => {
 
     });
 
 
   },
-  socketTask: function() {
-    var that = this;
-    SocketTask.onOpen(res => {
-      that.globalData.socketOpen = true;
-      console.log('监听 WebSocket 连接打开事件。', res)
-    })
-    SocketTask.onClose(onClose => {
-      console.log('监听 WebSocket 连接关闭事件。', onClose)
-      that.globalData.socketOpen = false;
-      this.webSocket()
-    })
-    SocketTask.onError(onError => {
-      console.log('监听 WebSocket 错误。错误信息', onError)
-      that.globalData.socketOpen = false
-    })
-    SocketTask.onMessage(onMessage => {
-      console.log('监听WebSocket接受到服务器的消息事件。服务器返回的消息', JSON.parse(onMessage.data))
-    })
-  },
-  wsConnect: function() {
-    // 创建Socket
-    let that = this
-    SocketTask = wx.connectSocket({
-      url: api.ChatWs + '/' + this.globalData.userInfo.openId,
-      data: 'data',
-      header: {
-        'content-type': 'application/json'
-      },
-      method: 'post',
-      success: function(res) {
-        console.log('WebSocket连接创建', res)
-        that.wsOnMessage();
-      },
-      fail: function(err) {
-        wx.showToast({
-          title: '网络异常!',
-        })
-        console.log(err)
-      },
-    })
-  },
+  // socketTask: function() {
+  //   var that = this;
+  //   SocketTask.onOpen(res => {
+  //     that.globalData.websocket.socketOpen = true;
+  //     console.log('监听 WebSocket 连接打开事件。', res)
+  //   })
+  //   SocketTask.onClose(onClose => {
+  //     console.log('监听 WebSocket 连接关闭事件。', onClose)
+  //     that.globalData.websocket.socketOpen = false;
+  //     this.webSocket()
+  //   })
+  //   SocketTask.onError(onError => {
+  //     console.log('监听 WebSocket 错误。错误信息', onError)
+  //     that.globalData.websocket.socketOpen = false
+  //   })
+  //   SocketTask.onMessage(onMessage => {
+  //     // console.log('监听WebSocket接受到服务器的消息事件。服务器返回的消息', JSON.parse(onMessage.data))
+  //   })
+  // },
+  // wsConnect: function() {
+  //   // 创建Socket
+  //   let that = this
+  //   SocketTask = wx.connectSocket({
+  //     url: api.ChatWs + '/' + this.globalData.userInfo.openId,
+  //     data: 'data',
+  //     header: {
+  //       'content-type': 'application/json'
+  //     },
+  //     method: 'post',
+  //     success: function(res) {
+  //       console.log('WebSocket连接创建', res)
+  //       that.wsOnMessage();
+  //     },
+  //     fail: function(err) {
+  //       wx.showToast({
+  //         title: '网络异常!',
+  //       })
+  //       console.log(err)
+  //     },
+  //   })
+  // },
   wsOnMessage:function(){
+    if (!this.globalData.websocket.changeBadge){
+        console.log("不监听badge")
+        return
+    }
     wx.onSocketMessage(onMessage => {
       console.log('监听WebSocket接受到服务器的消息事件。服务器返回的消息', JSON.parse(onMessage.data))
       var res = JSON.parse(onMessage.data)
@@ -80,6 +86,8 @@ App({
               text: res.data.messageBody
             })
           }
+        } else if (res.data.messageType == 1){
+          
         }
       } else {
         console.log(res)
@@ -89,8 +97,6 @@ App({
   },
 
 
-
-
   globalData: {
     userInfo: {
       openId: '',
@@ -98,7 +104,12 @@ App({
       avatarUrl: 'https://i.postimg.cc/RVbDV5fN/anonymous.png'
     },
     token: '',
-    socketOpen: false
+    websocket: {
+      socketOpen: false,
+      changeBadge: true,
+    }
+    
+    
   },
   testData: {
     userInfo: {
@@ -107,7 +118,6 @@ App({
       avatarUrl: 'https://4.bp.blogspot.com/-gKPdnJWscyI/VCIkF3Po4DI/AAAAAAAAmjo/fAKkTMyf8hM/s170/monster01.png'
     },
     token: 'Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJhdmF0YXJVcmwiOiJodHRwczovLzQuYnAuYmxvZ3Nwb3QuY29tLy1nS1BkbkpXc2N5SS9WQ0lrRjNQbzRESS9BQUFBQUFBQW1qby9mQUtrVE15ZjhoTS9zMTcwL21vbnN0ZXIwMS5wbmciLCJvcGVuSWQiOiIxIiwibmlja05hbWUiOiLmtYvor5XnlKjmiLcxIn0.NH3ISj2Fkircr8oB_w8-lZmf3QPt2tEOPx6Xrc-Bt8HAFu1oZIYOBYaevl8PS1xoaKkf4-8TBL2Jfx5E_uSbbkYj6WD5whHoWPy264AC3qP6ddIYFPDt3w5Ya8-FEZ26he6_mTSr0ceX-rMoFl_yiBSqoU0_H4XNAewsrTK8x3ow9qBI26eQlLDxHsZE-R3pA5sUm1IQEuV-pWGFgw6STNedoWJwX9Vq_SS4LnjOjmUZxI_xH3kPT38UAb-tvL-cM1_9XioP6H0G_9v4EhfDvnKZpmVXF4_qVzPy1VL_2VbTQr2AMoIqzP_FBSsCq2l6keP_BF6cnICJmGkqY3sLqw',
-    socketOpen: false
   },
   post: {
     cate: {

+ 1 - 0
wx-front/config/api.js

@@ -27,6 +27,7 @@ module.exports = {
 
   ChatIndex: ApiRootUrl + 'chat/index', //消息一览
   ChatForm: ApiRootUrl + 'chat/form', //消息框
+  ChatFlushUnread: ApiRootUrl + 'chat/flushUnread', //把所有未读设为已读
   ChatWs: WebSocktUrl+'ws',  //消息WebSocket连接
 
   CartList: ApiRootUrl + 'cart/index', //获取购物车的数据

+ 101 - 10
wx-front/pages/chat/chatForm/chatForm.js

@@ -1,6 +1,7 @@
 var util = require('../../../utils/util.js');
 var api = require('../../../config/api.js');
-// pages/chat/chatForm/chatForm.js
+var websocket = require('../../../services/websocket.js');
+// 参考:
 // https://blog.csdn.net/qq_35713752/article/details/78688311
 // https://blog.csdn.net/qq_35713752/article/details/80811397
 Page({
@@ -21,6 +22,7 @@ Page({
     scrollHeight: 0,
     newScrollHeight: 0,
     noMore: false,
+    input: '',
   },
 
   /**
@@ -33,8 +35,9 @@ Page({
       myAvatar: wx.getStorageSync('userInfo').avatarUrl,
       offsetTime: now.toISOString()
     })
-    this.getHistory();
 
+    this.getHistory();
+    this.openListen();
 
   },
 
@@ -46,21 +49,21 @@ Page({
     }).then(function(res) {
       if (res.errno === 0) {
         console.log(res.data);
+        
         that.setData({
           otherSide: res.data.otherSide,
           historyList: res.data.historyList.concat(that.data.historyList),
           goods: res.data.goods,
           isU1: res.data.isU1,
-          offsetTime: res.data.offsetTime,
+          offsetTime: res.data.offsetTime+"",
         });
+        
 
         if (res.data.historyList.length < that.data.size) {
           that.setData({
             noMore: true
           })
         }
-
-        console.log(that.data.historyList.length)
         if (that.data.historyList.length < 11) {
           wx.setNavigationBarTitle({
             title: that.data.otherSide.nickName
@@ -77,7 +80,7 @@ Page({
 
         } else {
           //重新设置scroll,scrollTop = 之前的scrollHeigth - 加入了数据后的scrollHeigth
-          let _this=that
+          let _this = that
           that.getScrollHeight().then((res) => {
             var scroll = res - _this.data.scrollHeight
             _this.setData({
@@ -92,6 +95,21 @@ Page({
       }
     })
   },
+  openListen:function(){
+    let that = this
+    websocket.listenChatForm(this.data.id).then(res => {
+      var newHistory = [{
+        chatId: res.chatId,
+        u1ToU2: res.senderId < res.receiverId ? true : false,
+        messageType: res.messageType,
+        messageBody: res.messageBody,
+        sendTime: res.sendTime,
+      }]
+      that.addHistoryList(newHistory)
+      that.openListen()
+
+    })
+  },
   toGoods: function(event) {
     let goodsId = event.target.dataset.id;
     wx.navigateTo({
@@ -104,19 +122,91 @@ Page({
       this.getHistory()
     }
   },
-  getScrollHeight: function () {
+  getScrollHeight: function() {
     let that = this
-    return new Promise(function (resolve, reject) {
+    return new Promise(function(resolve, reject) {
       var query = wx.createSelectorQuery()
       //#hei是位于scroll最低端的元素,求它离scroll顶部的距离,得出ScrollHeight
       query.select('#hei').boundingClientRect()
       query.selectViewport().scrollOffset()
-      query.exec(function (res) {
+      query.exec(function(res) {
         console.log("异步设置ScrollHeight" + res[0].top)
         resolve(res[0].top);
       })
     });
   },
+  inputChange: function(e) {
+    console.log(e.detail.value)
+    this.setData({
+      input: e.detail.value
+    })
+  },
+  sendMsg: function() {
+    if (this.data.input.trim() == '') {
+      this.setData({
+        input: '',
+      })
+      return
+    }
+    let that = this
+    var data = this.createMsg()
+    //通过webSocket发送消息
+    websocket.sendMessage(data).then(res => {
+      console.log(res)
+
+      var newHistory = [{
+        chatId: this.data.id,
+        u1ToU2: wx.getStorageSync('userInfo').openId < this.data.otherSide.openId ? true : false,
+        messageType: 1,
+        messageBody: this.data.input,
+        sendTime: util.formatTime(new Date()),
+      }]
+
+      that.addHistoryList(newHistory)
+
+    }).catch((res) => {
+      console.log(res)
+      util.showErrorToast('发送失败')
+    });
+
+  },
+  addHistoryList: function(historyList) {
+    //把新的数据加入目前的对话框
+    var newHistoryList = this.data.historyList.concat(historyList)
+    this.setData({
+      input: '',
+      historyList: newHistoryList,
+    })
+
+    //重新设置scroll
+    let _this = this
+    this.getScrollHeight().then((res) => {
+      var scroll = res - _this.data.scrollHeight
+      _this.setData({
+        scrollTop: 100000000,
+        scrollHeight: res,
+      })
+    })
+  },
+  createMsg: function() {
+    var msgType;
+  
+    if (this.data.historyList.length>1) {
+      msgType = 1
+    } else {
+      msgType = 2
+    }
+
+    var data = JSON.stringify({
+      chatId: this.data.id,
+      receiverId: this.data.otherSide.openId,
+      senderId: wx.getStorageSync('userInfo').openId,
+      goodsId: this.data.goods.id,
+      messageType: msgType,
+      messageBody: this.data.input
+    })
+    return data
+  },
 
   /**
    * 生命周期函数--监听页面初次渲染完成
@@ -143,7 +233,8 @@ Page({
    * 生命周期函数--监听页面卸载
    */
   onUnload: function() {
-
+    websocket.stopListenForm(this.data.id)
+    websocket.listenBadge()
   },
 
   /**

+ 4 - 4
wx-front/pages/chat/chatForm/chatForm.wxml

@@ -24,7 +24,7 @@
       <view wx:for="{{historyList}}" wx:key="{{index}}">
 
         <!-- 自己发送 -->
-        <view class='history' wx:if="{{((isU1 && item.u1ToU2) || (!isU1 && !item.u1ToU2)) && item.messageType!=2}}">
+        <view class='history' wx:if="{{((isU1 && item.u1ToU2) || (!isU1 && !item.u1ToU2)) && item.messageType!=4}}">
           <view class='time-view'>
             <text class='time'>{{item.sendTime}}</text>
           </view>
@@ -39,7 +39,7 @@
         </view>
 
         <!-- 对方发送 -->
-        <view class='history' wx:elif="{{item.messageType!=2}}" id="msg{{item.sendTime}}">
+        <view class='history' wx:elif="{{item.messageType!=4}}" id="msg{{item.sendTime}}">
           <view class='time-view'>
             <text class='time'>{{item.sendTime}}</text>
           </view>
@@ -70,10 +70,10 @@
     <view class="input">
 
       <view class="content">
-        <input class='' focus='{{openComment}}' placeholder="" maxlength='800' confirm-type="done" bindconfirm='done' value='{{}}' />
+        <input class='' focus='{{openComment}}' placeholder="" maxlength='800' confirm-type="done" bindconfirm='done' value='{{input}}' bindinput="inputChange" />
 
       </view>
-      <view class='send'>发送</view>
+      <view class='send' bindtap='sendMsg'>发送</view>
     </view>
   </view>
 </view>

+ 63 - 16
wx-front/pages/chat/chatIndex/chatIndex.js

@@ -1,21 +1,11 @@
 var util = require('../../../utils/util.js');
 var api = require('../../../config/api.js');
+var websocket = require('../../../services/websocket.js');
 
 var app = getApp();
 
 Page({
   data: {
-    cartGoods: [],
-    cartTotal: {
-      "goodsCount": 0,
-      "goodsAmount": 0.00,
-      "checkedGoodsCount": 0,
-      "checkedGoodsAmount": 0.00
-    },
-    isEditCart: false,
-    checkedAllStatus: true,
-    editCartList: [],
-
     chatList: [],
     offsetTime: null,
     size: 10,
@@ -23,7 +13,42 @@ Page({
   onLoad: function(options) {
     // 页面初始化 options为页面跳转所带来的参数
 
+  },
+  openListen: function() {
+    let that = this
+    websocket.listenChatIndex().then(res => {
+
+      //存在与目前list中
+      let chatList = this.data.chatList
+      for (var i in chatList) {
+        if (chatList[i].lastChat.chatId == res.chatId) {
+          var target = chatList[i]
+          var newChatList = []
+
+
+          target.unreadCount++;
+          target.u1ToU2 = res.senderId < res.receiverId ? true : false
+          target.lastChat.messageType = res.messageType
+          target.lastChat.messageBody = res.messageBody
+          target.lastChat.sendTime = res.sendTime
 
+          chatList.splice(i, 1);
+          console.log("splice")
+          console.log(chatList)
+
+          newChatList.push(target)
+          newChatList = newChatList.concat(chatList)
+
+          that.setData({
+            chatList: newChatList
+          })
+          that.openListen()
+          return
+        }
+      }
+      //不存在, 后端可以专门写个api
+      that.onShow()
+    })
   },
   onReady: function() {
     // 页面渲染完成
@@ -32,16 +57,17 @@ Page({
   onShow: function() {
     // 页面显示
     let now = new Date();
-    console.log(now.toISOString())
-
     this.setData({
-      offsetTime: now.toISOString()
+      offsetTime: now.toISOString(),
+      chatList: []
     })
 
     this.getChatList();
+    this.openListen();
   },
   onHide: function() {
     // 页面隐藏
+    websocket.listenBadge()
 
   },
   onUnload: function() {
@@ -64,7 +90,27 @@ Page({
       }
     })
   },
-  onPullDownRefresh: function () {
+  navForm: function(e) {
+    var chatId = e.currentTarget.dataset.id
+    var index = e.currentTarget.dataset.index
+    var chatList = this.data.chatList
+
+    //减少tapbar的badge
+    var lessBadge = chatList[index].unreadCount
+    websocket.lessBadge(lessBadge)
+
+    //减少列表用户的badge
+    chatList[index].unreadCount = 0
+    this.setData({
+      chatList: chatList
+    })
+
+    wx.navigateTo({
+      url: '/pages/chat/chatForm/chatForm?id=' + chatId,
+    })
+
+  },
+  onPullDownRefresh: function() {
     console.log("上拉刷新")
     this.setData({
       chatList: [],
@@ -78,7 +124,7 @@ Page({
 
 
   },
-  onReachBottom: function () {
+  onReachBottom: function() {
     console.log("拉到底")
     let chatList = this.data.chatList;
     let offsetTime = chatList[chatList.length - 1].offsetTime;
@@ -88,4 +134,5 @@ Page({
 
     this.getChatList()
   },
+
 })

+ 2 - 2
wx-front/pages/chat/chatIndex/chatIndex.wxml

@@ -14,7 +14,7 @@
 
   <view class="result-list" wx:if="{{chatList.length > 0}}">
 
-    <navigator class="chat" url='/pages/chat/chatForm/chatForm?id={{item.lastChat.chatId}}' wx:for="{{chatList}}">
+    <view class="chat" bindtap='navForm' data-id='{{item.lastChat.chatId}}' data-index='{{index}}'  wx:for="{{chatList}}" wx:key="{{index}}">
       <view class="item">
         <view class='avatar-item'>
           <image class="avatar" mode='aspectFill' src="{{item.otherSide.avatarUrl}}"></image>
@@ -34,7 +34,7 @@
         </view>
         <image class="img" mode='aspectFill' src="{{item.goods.primaryPicUrl}}"></image>
       </view>
-    </navigator>
+    </view>
     
 
   </view>

+ 234 - 0
wx-front/services/websocket.js

@@ -0,0 +1,234 @@
+var app = getApp();
+const api = require('../config/api.js');
+const util = require('../utils/util.js');
+
+var SocketTask
+var socketOpen = false
+var badge = 0
+var newMsgList  = []
+
+
+/**
+ * 创建websocket连接
+ */
+function wsConnect() {
+
+  let that = this
+  var openId = wx.getStorageSync('userInfo').openId
+  // 创建Socket
+  return new Promise(function(resolve, reject) {
+    SocketTask = wx.connectSocket({
+      url: api.ChatWs + '/' + openId,
+      data: 'data',
+      header: {
+        'content-type': 'application/json'
+      },
+      method: 'post',
+      success: function(res) {
+        console.log('WebSocket连接创建', res)
+        listenBadge()
+      },
+      fail: function(err) {
+        wx.showToast({
+          title: '网络异常!',
+        })
+        console.log("err")
+        reject("网络异常!")
+      },
+    })
+    console.log(SocketTask)
+    socketTask(SocketTask)
+
+    resolve(SocketTask)
+  })
+}
+
+/**
+ * 监听websocket状态
+ */
+function socketTask(SocketTask) {
+  let that = this
+
+  SocketTask.onOpen(res => {
+    socketOpen = true;
+    console.log('监听 WebSocket 连接打开事件。', res)
+  })
+  SocketTask.onClose(onClose => {
+    console.log('监听 WebSocket 连接关闭事件。', onClose)
+    socketOpen = false;
+    that.wsConnect()
+  })
+  SocketTask.onError(onError => {
+    console.log('监听 WebSocket 错误。错误信息', onError)
+    socketOpen = false
+  })
+  SocketTask.onMessage(onMessage => {
+    // console.log('监听WebSocket接受到服务器的消息事件。服务器返回的消息', JSON.parse(onMessage.data))
+  })
+}
+
+
+function sendMessage(data) {
+  var that = this;
+  return new Promise(function(resolve, reject) {
+    if (socketOpen) {
+      wx.sendSocketMessage({
+        data: data,
+        success: res => {
+          resolve(res);
+        },
+        fail: res => {
+          reject(res);
+        }
+      })
+    } else {
+      reject("未建立websocket连接");
+    }
+
+  })
+}
+
+/**
+ * 初始化badge未读数
+ */
+function initBadge() {
+  return new Promise(function(resolve, reject) {
+    wx.onSocketMessage(onMessage => {
+      var res = JSON.parse(onMessage.data)
+      if (res.errno === 0) {
+        if (res.data.messageType == 3 && res.data.messageBody != 0) {
+          badge = res.data.messageBody
+          wx.setTabBarBadge({
+            index: 3,
+            text: badge
+          })
+
+          resolve("初始化未读数badge : " + badge)
+        }
+      } else {
+        console.log(res)
+        reject(res)
+      }
+    })
+  })
+}
+function listenBadge() {
+  // return new Promise(function (resolve, reject) {
+    wx.onSocketMessage(onMessage => {
+      var res = JSON.parse(onMessage.data)
+      if (res.errno === 0) {
+        if (res.data.messageType == 3 && res.data.messageBody != 0) {
+          badge = res.data.messageBody
+          wx.setTabBarBadge({
+            index: 3,
+            text: badge+""
+          })
+
+          console.log("初始化未读数badge : " + badge)
+        } else if (res.data.messageType == 1){
+          badge++
+          wx.setTabBarBadge({
+            index: 3,
+            text: badge + ""
+          })
+          console.log("接收到新消息,更新badge : " + badge)
+        }
+      } else {
+        console.log(res)
+        reject(res)
+      }
+    })
+  // })
+}
+
+/**
+ * 消息form页监听消息
+ */
+function listenChatForm(chatId) {
+  return new Promise(function(resolve, reject) {
+    wx.onSocketMessage(onMessage => {
+      var res = JSON.parse(onMessage.data)
+      if (res.errno === 0) {
+        if (res.data.messageType == 1 && res.data.chatId == chatId) {
+          console.log("消息Form监听到新消息 : " + res.data.messageBody)
+          var newMsg = res.data
+          newMsgList.push(newMsg)
+          console.log(newMsgList)
+          resolve(newMsg)
+        }
+      } else {
+        console.log(res)
+        reject(res)
+      }
+    })
+  })
+}
+
+/**
+ * 关闭对form页的监听,其实就是把期间收到的消息刷入数据库
+ */
+function stopListenForm(chatId){
+  if (newMsgList.length > 0){
+    newMsgList = []
+    util.request(api.ChatFlushUnread + '/' + chatId, {},"POST").then((res) => {
+      if(res.errno == 0){
+        console.log("把unread刷入数据库成功")
+        
+      }else{
+        console.log(res)
+      }
+    })
+  }
+}
+
+/**
+ * 消息列表页监听消息
+ */
+function listenChatIndex() {
+  return new Promise(function(resolve, reject) {
+    wx.onSocketMessage(onMessage => {
+      var res = JSON.parse(onMessage.data)
+      if (res.errno === 0) {
+        if (res.data.messageType == 1) {
+          console.log("消息列表监听到新消息 : " + res.data.messageBody)
+          badge++
+          wx.setTabBarBadge({
+            index: 3,
+            text: badge + ""
+          })
+          resolve(res.data)
+        }
+      } else {
+        console.log(res)
+        reject(res)
+      }
+    })
+  })
+}
+
+
+function lessBadge(less) {
+  badge = badge - less
+  if (badge == 0) {
+    wx.removeTabBarBadge({
+      index: 3,
+    })
+  } else {
+    wx.setTabBarBadge({
+      index: 3,
+      text: badge + ""
+    })
+  }
+
+}
+
+module.exports = {
+  wsConnect,
+  socketTask,
+  sendMessage,
+  listenChatForm,
+  listenChatIndex,
+  lessBadge,
+  listenBadge,
+  stopListenForm,
+};