signalr 应用于微信小程序(二)

前言

本节基于一,为2017年写的脚本库。

正文

我们连接的是websocket那么我们需要看的是ws:

这里看到需要的参数其实只要connecttoken我们是没有的,那么如果得到的呢?

是网络请求还是本地生成的?网络请求的可能性比较大。

经过我查看源码是ajax得到的,那么我们应该看xhr了。

找到如何得到token的。

上图所示这样就可以看到token如何获取。

经过上诉分析后,只要收发包一致,那么就可以搞定。

代码如下:

2017年写的,代码很差,见谅。

const protocal = {
  protocol: "json",
  version: 1
};

const MessageType = {
  /** Indicates the message is an Invocation message and implements the {@link InvocationMessage} interface. */
  Invocation: 1,
  /** Indicates the message is a StreamItem message and implements the {@link StreamItemMessage} interface. */
  StreamItem: 2,
  /** Indicates the message is a Completion message and implements the {@link CompletionMessage} interface. */
  Completion: 3,
  /** Indicates the message is a Stream Invocation message and implements the {@link StreamInvocationMessage} interface. */
  StreamInvocation: 4,
  /** Indicates the message is a Cancel Invocation message and implements the {@link CancelInvocationMessage} interface. */
  CancelInvocation: 5,
  /** Indicates the message is a Ping message and implements the {@link PingMessage} interface. */
  Ping: 6,
  /** Indicates the message is a Close message and implements the {@link CloseMessage} interface. */
  Close: 7,
}


export class HubConnection {

  constructor() {
    this.openStatus = false;
    this.methods = {};
    this.negotiateResponse = {};
    this.connection = {};
    this.url = "";
    this.invocationId = 0;
    this.callbacks = {};
  }


  start(url, queryString) {
    var negotiateUrl = url + "/negotiate";
    if (queryString) {
      for(var query in queryString){
        negotiateUrl += (negotiateUrl.indexOf("?") < 0 ? "?" : "&") + (`${query}=` + encodeURIComponent(queryString[query]));
      }

    }
    var timestamp = (new Date()).valueOf()/1000;
    wx.request({
      url: negotiateUrl +'&_='+timestamp+'',
      method: "get",
      async: false,
      success: res => {
        console.log(res.data);
        this.negotiateResponse = res.data;
        this.startSocket(negotiateUrl.replace("/negotiate",""));
      },
      fail: res => {
        console.error(`requrst ${url} error : ${res}`);
        return;
      }
    });

  }

  startSocket(url) {
    var token =this.negotiateResponse.ConnectionToken;
    token= token.replace(' ','+');
    console.log(token);
    var tid = Math.floor(Math.random() * 11);
    url += (url.indexOf("?") < 0 ? "?" : "&") + ('connectionToken=' + encodeURIComponent(token) + '&transport=webSockets&clientProtocol=' + 1.5 + '&tid=' + tid);
    url = url.replace(/^http/, "ws");
    this.url = url;
    if (this.connection != null && this.openStatus) {
      return;
    }


    this.connection = wx.connectSocket({
      url: url,
      method: "get"
    })

    this.connection.onOpen(res => {
      console.log(`websocket connectioned to ${this.url}`);
      this.sendData(protocal);
      this.openStatus = true;
      this.onOpen(res);
    });

    this.connection.onClose(res => {
      console.log(`websocket disconnection`);
      this.connection = null;
      this.openStatus = false;
      this.onClose(res);
    });

    this.connection.onError(res => {
      console.error(`websocket error msg: ${msg}`);
      this.close({
        reason: msg
      });
      this.onError(res)
    });

    this.connection.onMessage(res => this.receive(res));
  }


  on(method, fun) {
    if (this.methods[method]) {
      this.methods[method].push(fun);
      console.log("方法" + method+"进入");
    } else {
      console.log("方法" + method + "进入");
      this.methods[method] = [fun];
    }
  }

  onOpen(data) {}

  onClose(msg) {

  }

  onError(msg) {

  }


  close(data) {
    if (data) {
      this.connection.close(data);
    } else {
      this.connection.close();
    }

    this.openStatus = false;
  }

  sendData(data, success, fail, complete) {
    console.log(data,"数据调用");
    this.connection.send({
      data: JSON.stringify(data), //
      success: success,
      fail: fail,
      complete: complete
    });
    console.log(this.connection,'test');
  }


  receive(data) {
    // if(data.data.length>3){
    //   data.data = data.data.replace('{}', "")
    // }
   // console.log(data,"数据接收");
    var message =JSON.parse(data.data);
    var messageDetail = message.M;
    //console.log(messageDetail,"收到的数据");
    var message = JSON.parse(data.data.replace(new RegExp("", "gm"),""));
    //console.warn(typeof (messageDetail),"typeof (messageDetail)");
    if (typeof (messageDetail) != 'undefined' && typeof (messageDetail[0]) !='undefined')
    {
      var invokemessage=messageDetail[0];
      this.invokeClientMethod(message);
    }
    //留用数据类型
    // switch (message.type) {
    //   case MessageType.Invocation:
    //     this.invokeClientMethod(message);
    //     break;
    //   case MessageType.StreamItem:
    //     break;
    //   case MessageType.Completion:
    //     var callback = this.callbacks[message.invocationId];
    //     if (callback != null) {
    //       delete this.callbacks[message.invocationId];
    //       callback(message);
    //     }
    //     break;
    //   case MessageType.Ping:
    //     // Don't care about pings
    //     break;
    //   case MessageType.Close:
    //     console.log("Close message received from server.");
    //     this.close({
    //       reason: "Server returned an error on close"
    //     });
    //     break;
    //   default:
    //     this.invokeClientMethod(message);
    //     //console.warn("Invalid message type: " + message.type);
    // }


  }


  send(functionName) {

    var args = [];
    for (var _i = 1; _i < arguments.length; _i++) {
      args[_i - 1] = arguments[_i];
    }

    this.sendData({
      M: functionName,
      A: args,
      H: "chathub",
      type: MessageType.Invocation,
      I: this.invocationId
    });
    this.invocationId++;
  }


  invoke(functionName) {
    var args = [];
    for (var _i = 1; _i < arguments.length; _i++) {
      args[_i - 1] = arguments[_i];
    }

    var _this = this;
    var id = this.invocationId;
    var p = new Promise(function (resolve, reject) {

      _this.callbacks[id] = function (message) {
        if (message.error) {
          reject(new Error(message.error));
        } else {
          resolve(message.result);
        }
      }

      _this.sendData({
        M: functionName,
        A: args,
        H: "chathub",
        type: MessageType.Invocation,
        I: _this.invocationId
      }, null, function (e) {
        reject(e);
      });

    });
    this.invocationId++;
    return p;

  }

  invokeClientMethod(message) {
    console.log(message,"message");
    //得到启用的方法
    var methods = this.methods[message.M[0].M.toLowerCase()];
    //console.log(this.methods,"methods方法");
    //console.log(message.M[0].M.toLowerCase(),"methods数据");
    if (methods) {
      methods.forEach(m => m.apply(this, message.M[0].A));
      if (message.invocationId) {
        // This is not supported in v1. So we return an error to avoid blocking the server waiting for the response.
        var errormsg = "Server requested a response, which is not supported in this version of the client.";
        console.error(errormsg);
        this.close({
          reason: errormsg
        });
      }
    } else {
      console.warn(`No client method with the name '${message.target}' found.`);
    }
  }
}
posted @ 2020-07-03 15:34  敖毛毛  阅读(1020)  评论(0编辑  收藏  举报