V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
xoxo419
V2EX  ›  问与答

如果调用服务端的 Socket?

  •  
  •   xoxo419 · 2017-10-09 09:46:46 +08:00 · 2314 次点击
    这是一个创建于 2597 天前的主题,其中的信息可能已经有所发展或是发生改变。

    公司要做一个扫码开箱的盖. 项目是外包出去的 硬件设备, 服务端, APP 都是外包做的. 我自己是做 PHP 的 然后公司现在又想加一个微信端的[我自己准备用小程序来实现].

    现在他们的接口是用 socket[TCP]来做的, 我之前写接口都是 HTTP. 所以不太懂 socket. 看的那是一头雾水.

    现在外包那就只给了一份《协议文档》, 没有 PHP 的示例, 求示例.

    第 1 条附言  ·  2017-10-09 11:33:28 +08:00

    Socket服务端是JAVA写的, 说是基于TCP的.

    微信小程序 官方文档-connectSocket

    url	String	是	开发者服务器接口地址,必须是 wss 协议,且域名必须是后台配置的合法域名
    

    那是不是就不能用了?

    如果上面不能用, 我是否可以用PHP来做, 然后微信小程序再调用我PHP的HTTP的API?

    16 条回复    2017-10-17 08:37:37 +08:00
    xoxo419
        1
    xoxo419  
    OP
       2017-10-09 09:47:31 +08:00
    lean
        2
    lean  
       2017-10-09 10:20:05 +08:00 via Android
    在你们的服务器对接微信,然后用微信的信息,根据协议文档 php tcp 对接你们的设备
    qiayue
        3
    qiayue  
       2017-10-09 10:31:43 +08:00   ❤️ 1
    php 用 swoole 来起 socket 服务。
    如果 php 只是当做客户端,连接对方 socket 服务,则最简单的方式是用 fsockopen,然后 fwrite,fclose 就可以了。

    具体怎么发,给你个原理展示:
    $str = '00 01 02 03 04';//字符串形式的十六进制数据
    $arr = str_split(str_ireplace(' ', '', $cmd_str), 2);//去掉空格后,2 字符一段切分成数组
    $byte_arr = array();
    foreach ($arr as $h) {
    ~~~~$byte_arr[] = chr(hexdec($h));
    }
    $byte_str = implode('', $byte_arr);
    $fp = fsockopen($host, $port, $errno, $errstr, 5);
    fwrite($fp, $byte_str);
    fclose($fp);
    qiayue
        4
    qiayue  
       2017-10-09 10:32:40 +08:00
    勘误,第二行代码有个变量名写错了
    $arr = str_split(str_ireplace(' ', '', $str), 2);//去掉空格后,2 字符一段切分成数组
    qooweds
        5
    qooweds  
       2017-10-09 10:49:26 +08:00
    第 0 个字节放魔数,第 1 个字节放消息类型,依此类推
    不过消息头和消息体没明白什么意思,消息头放 TCP 头里?感觉不太像啊
    xoxo419
        6
    xoxo419  
    OP
       2017-10-09 11:10:54 +08:00
    @qiayue
    @qooweds 那这个设备 ID 怎么传呢?
    qooweds
        7
    qooweds  
       2017-10-09 11:24:34 +08:00
    @xoxo419 应该是 string 转成字节数组吧?
    xoxo419
        8
    xoxo419  
    OP
       2017-10-09 11:29:20 +08:00
    @qiayue
    @qooweds 我也不太清楚..... 上面的 4-7 还有<固定的东西作为头部><变动的东西作为体> 是什么东东, 没有相关的资料可以参考下 ? 搜索都不知道是不是. 上面的表是一个 TCP 的一条数据?
    xoxo419
        9
    xoxo419  
    OP
       2017-10-09 11:36:02 +08:00
    网上找的一段 socket 客户端连接方式. [转自]( http://www.cnblogs.com/kravis/p/5707898.html)
    ```
    <?php
    error_reporting(E_ALL);
    set_time_limit(0);


    $ip = '127.0.0.1';
    $port = 8888;

    // 1. 创建
    $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);

    if( $socket == FALSE ) {
    echo 'create fail: ' . socket_strerror(socket_last_error());
    } else {
    echo 'OK';
    }

    // 2. 链接
    echo 'we will try to connect ' . $ip .':' . $port . '\r\n----';
    $result = socket_connect($socket, $ip, $port);
    if ( $result == FALSE) {

    }

    $in = 'HO ';
    $in .= 'first blood--------';
    $out = '';

    // 3. 向服务端写入
    if( !socket_write($socket, $in, strlen($in)) ) {
    echo 'write fail: ' . socket_strerror(socket_last_error());
    } else {
    echo '-----send to server succefully! \r\n----';
    echo 'the content is ' . $in;
    }

    // 3. 从服务端读取
    while ( $out = socket_read($socket, 8129) ) {
    echo '-----receive from server succefully!\r\n------';
    echo 'the contents is ' . $out;
    }

    // 4. 关闭
    echo '----close socket ...';
    socket_close($socket);
    echo 'closed ok.';
    ```

    但这个并没有像上面图片那样分段的, 服务端怎么知道我发送的是设备 ID?
    qiayue
        10
    qiayue  
       2017-10-09 11:45:11 +08:00
    所有数据都是十六进制拼接在一起的
    每一个字节占 2 位
    图片中括号里边的数字表示这个数据占几个字节
    帧头 1 字节
    消息类型 1 字节
    长度 2 字节
    设备 ID 4 字节

    这样从开头数起,设备 ID 就是在第 4~7 字节(从 0 开始)
    qiayue
        11
    qiayue  
       2017-10-09 11:49:55 +08:00
    ws 是 websocket 的协议
    wss 与 ws 类似于 https 与 http 的关系
    小程序用的话,你就要在服务器里搞一个 websocket 服务来做代理了
    xoxo419
        12
    xoxo419  
    OP
       2017-10-09 13:32:14 +08:00
    @qiayue #11 我用 php 去调用, 然后把这段写成 API, 这种方式不行么?
    xoxo419
        13
    xoxo419  
    OP
       2017-10-09 14:59:38 +08:00
    @xoxo419 #9

    ```
    $in = 'HO ';
    $in .= 'first blood--------';
    $out = '';
    ```

    #9 代码中为什么$in 不直接写要分开两段?
    xoxo419
        14
    xoxo419  
    OP
       2017-10-09 15:39:46 +08:00
    @qiayue #10 这个没看懂.

    我找到一份 JAVA 的,
    ```

    public String toString() {
    return "NettyMessage{" +
    "magic=" + magic +
    ", msgType=" + msgType +
    ", reserve=" + reserve +
    ", devId=" + devId +
    ", can1=" + can1 +
    ", can2=" + can2 +
    ", can3=" + can3 +
    ", can3_num=" + can3_num +
    ", rt=" + rt +
    '}';
    }
    ```

    ```
    SocketService.client.writeAndFlush(builder.build());
    ```

    这种是什么格式? PHP 如何可以转成这样的格式?
    mengzhuo
        15
    mengzhuo  
       2017-10-09 16:41:00 +08:00 via iPhone
    这个文档不标准啊,
    各个数据必须标注类型和长度,而且用个 excel 写……我也是醉了
    xoxo419
        16
    xoxo419  
    OP
       2017-10-17 08:37:37 +08:00
    @qiayue 代理服务器, 需要 nginx 配合么, 还是搭建一 websocket 服务器? 找了很多资料也没有找到配置的方法.
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1043 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 20:26 · PVG 04:26 · LAX 12:26 · JFK 15:26
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.