文档中心 > 开发指南

一、配置

参考文章:开发小游戏(服务端开发看)

参考文章《外部域名添加》的开通云服务和添加章节。

二、空小游戏项目发起Websocket请求

创建项目

后台创建项目

参考文章:创建与信息完善

参考文章的第一章。

将域名igo-open-demo.taobao.com配置到后台上,下文会用到;

IDE创建项目

选择对应的项目,然后选择设置项目保存路径,点击【确定】。

开发

定义测试函数

测试服务器(仅做演示用):

wss://igo-open-demo.taobao.com/websocket/test

代码:

const websocketTest = () => {
  const socketTask = my.connectSocket({
    url: 'wss://igo-open-demo.taobao.com/websocket/test', // 开发者服务器接口地址,必须是 wss 协议
    multiple: true    // 多连接模式,才会返回 SocketTask
    , success: (res) => {
      console.log('WebSocket open success', res);
    }, fail: (err) => {
      // 如果这里出错了,就要去执行兜底逻辑,比如重新连接
      console.error('WebSocket open error', err);
    }
  });
  socketTask.onOpen(res => {
    console.log(`WebSocket 已连接,socketTaskID = ${res.data.socketTaskID}`);
    socketTask.send({
      data: 'hi'
    });

    // SocketTask 目前支持多连接。而 my.connectSocket 不支持多连接,所以建议使用SocketTask。
    const second = my.connectSocket({
      url: 'wss://igo-open-demo.taobao.com/websocket/test', // 开发者服务器接口地址,必须是 wss 协议
      multiple: true    // 多连接模式,才会返回 SocketTask
      , success: (res) => {
        console.log('WebSocket open success', res);
      }, fail: (err) => {
        // 如果这里出错了,就要去执行兜底逻辑,比如重新连接
        console.error('WebSocket open error', err);
      }
    });
    second.onOpen(res => {
      console.log(`WebSocket 已连接,socketTaskID = ${res.data.socketTaskID}`);

      try {
        const base64 = utils.arrayBufferToBase64(new Uint8Array([11, 22, 33]).buffer);
        console.log('base64', base64);
        second.send({
          data: base64,
          isBuffer: true, // 标记为二进制数据
          success: (res) => {
            console.log('second.send success', res);
          },
          fail: (err) => {
            console.error('second.send error', err);
          },
          complete: (res) => {
            console.log('second.send complete', res);
          }
        });
      } catch (error) {
        console.log('onOpen Error:', error);
      }
    });
    second.onMessage((res) => {
      console.log('second.onMessage 接收到了消息', res.data, res?.data?.isBuffer);
      try {
        if (res?.data?.isBuffer) { // 判断是否为二进制数据
          const arrayBuffer = utils.base64ToArrayBuffer(res.data?.data);
          console.log('receive arrayBuffer:', arrayBuffer);
          my.alert({ content: new Uint8Array(arrayBuffer || []).toString(), title: 'second 收到' });
        }
      } catch (error) {
        console.error('second onMessage Error:', error);
      }
    });
  });
  socketTask.onClose((res) => {
    console.log('WebSocket.onClose 连接已关闭!', res);
  });
  socketTask.onError((res) => {
    console.log('WebSocket.onError 连接失败!', res);
  });
  socketTask.onMessage((res) => {
    console.log('WebSocket.onMessage 接收到了消息', res.data);
  });
}

调用

在game.js的代码尾部调用测试函数

websocketTest();

调试

IDE调试

真机调试

打开云构建

生成调试二维码

点击构建日志可以查看构建日志

用权限的账号扫码进入游戏

设置权限:设置成员

查看【真机调试】日志

处理二进制

目前淘宝小游戏的http协议不支持二进制数据传输,仅支持字符串发送。所以在例子中将二进制数据转化base64后发送。同时后端发送过来的数据也会被转化成字符串数据,前端也将其解码成二进制数据;注意发送二进制数据要将isBuffer设置为true,在解析的时候判断isBuffer为真则进行二进制转换;

utils.js请查看附录。

二进制转化为base64

const base64 = utils.arrayBufferToBase64(new Uint8Array([11, 22, 33]).buffer);
console.log('base64', base64);
second.send({
  data: base64,
  isBuffer: true, // 标记为二进制数据
  success: (res) => {
    console.log('second.send success', res);
  },
  fail: (err) => {
    console.error('second.send error', err);
  },
  complete: (res) => {
    console.log('second.send complete', res);
  }
});

base64转化为二进制

second.onMessage((res) => {
  console.log('second.onMessage 接收到了消息', res.data, res?.data?.isBuffer);
  try {
    if (res?.data?.isBuffer) { // 判断是否为二进制数据
      const arrayBuffer = utils.base64ToArrayBuffer(res.data?.data);
      console.log('receive arrayBuffer:', arrayBuffer);
      my.alert({ content: new Uint8Array(arrayBuffer || []).toString(), title: 'second 收到' });
    }
  } catch (error) {
    console.error('second onMessage Error:', error);
  }
});

多连接

部分游戏有建立多个websocket通讯的需求,SocketTask 目前支持多连接,老接口 my.connectSocket 不支持多连接,请注意区别使用。

三、在cocos使用websocket

2.x文档

3.x文档

使用cocos引擎进行websocket通讯,不需要考虑二进制和字符串互转的问题,cocos引擎部分版本支持多连接,请参考下表:

引擎大版本

支持版本

2.x

待发布,具体参考cocos的发版说明;若急用请在GitHub下载cocos 2.4.15 的websocket代码;

3.x

v3.8.4

四、在laya使用websocket

2.x文档

3.x文档

使用laya引擎进行websocket通讯,不需要考虑二进制和字符串互转的问题,同时laya引擎也支持多连接。

五、附录

utils.js

const utils = {
  /**
     * @param {Object} target
     * @param {Object} origin
     * @param {String} methodName
     * @param {String} targetMethodName
     */
  cloneMethod (target, origin, methodName, targetMethodName) {
    if (origin[methodName]) {
      targetMethodName = targetMethodName || methodName;
      target[targetMethodName] = origin[methodName].bind(origin);
    }
  },

  /**
     *
     * @param {String} str
     * @returns
     */
  encode (str) {
    let encodings = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
    const string = String(str);
    let result = '';
    let currentIndex = 0;
    let sum = void 0;
    while (string.charAt(0 | currentIndex) || (encodings = '=', currentIndex % 1)) {
      currentIndex += 0.75;
      const currentCode = string.charCodeAt(currentIndex);
      if (currentCode > 255) {
        // Cannot handle when it is greater than 255
        throw new Error('"btoa" failed');
      }
      sum = sum << 8 | currentCode;
      const encodeIndex = 63 & sum >> 8 - currentIndex % 1 * 8;
      result += encodings.charAt(encodeIndex);
    }

    return result;
  },

  /**
     *
     * @param {String} str
     */
  decode (str) {
    const encodings = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
    let res = '';
    const string = String(str).replace(/[=]+$/, '');
    let o;
    let r;
    let i = 0;
    let currentIndex = 0;
    while (r = string.charAt(currentIndex)) {
      currentIndex += 1;
      r = encodings.indexOf(r);
      if (~r) {
        o = i % 4 ? 64 * o + r : r;
        if (i++ % 4) {
          res += String.fromCharCode(255 & o >> (-2 * i & 6));
        }
      }
    }

    return res;
  },

  /**
     *
     * @param {ArrayBuffer} buffer
     */
  arrayBufferToBase64 (buffer) {
    return utils.encode(utils.arrayBufferToString(buffer));
  },

  /**
     *
     * @param {String} base64
     */
  base64ToArrayBuffer (base64) {
    return utils.stringToArrayBuffer(utils.decode(base64));
  },

  /**
     *
     * @param {ArrayBuffer} buffer
     */
  arrayBufferToString (buffer) {
    let result = '';
    const uintArray = new Uint8Array(buffer);
    const byteLength = uintArray.byteLength;
    for (let i = 0; i < byteLength; i++) {
      result += String.fromCharCode(uintArray[i]);
    }
    return result;
  },

  /**
     *
     * @param {String} string
     */
  stringToArrayBuffer (string) {
    const length = string.length;
    const uintArray = new Uint8Array(length);
    for (let i = 0; i < length; i++) {
      uintArray[i] = string.charCodeAt(i);
    }
    return uintArray.buffer;
  },
};

module.exports = utils;

FAQ

关于此文档暂时还没有FAQ
返回
顶部