递归火山软件开发平台

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
热搜: 火山 源码 类库
查看: 122|回复: 0
打印 上一主题 下一主题

[安卓] 【源代码共享】安卓WebSocket服务端

[复制链接]

75

主题

338

帖子

1985

积分

核心用户

雪中情

Rank: 9Rank: 9Rank: 9

积分
1985
QQ
跳转到指定楼层
楼主
发表于 6 天前 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 xuezhq 于 2025-9-20 20:23 编辑

安卓没有发现合适的 WebSocket服务端 ,特使用HP_TCP服务写了一个WebSocket服务端;
使用方法:
1、建立变量并引用类【WebSocket服务器】
2、变量.启动 (“服务IP地址”, 端口号)
3、启用“WebSocket服务器_数据进入”事件 来接受数据
4、使用 变量.发送数据 (连接ID, 1, "要发送的文本数据内容")

已经通过现有的WebSocket在线工具测试,PING/PONG帧暂时未做,大部分都是发的文本数据来保活,未完成或其他需要完善的功能也可以帮忙完善一下,但完善后还请务必回馈一下!

  1. <火山程序 类型 = "通常" 版本 = 1 />

  2. 类 WebSocket服务器 <折叠>
  3. {
  4.     变量 服务器 <类型 = HP_TCP服务器>
  5.     变量 ""
  6.     变量 "// 客户端ID" <类型 = 整数数组类>
  7.     变量 "// 客户端保活" <类型 = 整数数组类 注释 = "客户端的最后通讯时间">
  8.     变量 "// 客户端握手" <类型 = 整数数组类 注释 = "0未完成握手,1已完成握手">
  9.     变量 "// 锁_客户端" <参考 类型 = 线程写锁类 注释 = "防止非 WS 协议连接">

  10.     常量 关闭码_正常关闭 <公开 类型 = 文本型 值 = "1000" 注释 = "正常关闭(连接完成预期目的)">
  11.     常量 关闭码_端点离开 <公开 类型 = 文本型 值 = "1001" 注释 = "端点离开(如客户端关闭页面、服务器下线)">
  12.     常量 关闭码_协议错误 <公开 类型 = 文本型 值 = "1002" 注释 = "协议错误(对方发送了不符合协议的帧)">
  13.     常量 关闭码_不支持的数据类型 <公开 类型 = 文本型 值 = "1003" 注释 = "不支持的数据类型(如服务器不接受二进制帧)">
  14.     常量 关闭码_异常关闭 <公开 类型 = 文本型 值 = "1006" 注释 = "异常关闭(未发送关闭帧直接断开,无关闭码)">
  15.     常量 关闭码_服务器内部错误导致关闭 <公开 类型 = 文本型 值 = "1011" 注释 = "服务器内部错误导致关闭">

  16.     方法 启动 <公开 类型 = 逻辑型 折叠>
  17.     参数 服务器地址 <类型 = 文本型 @默认值 = "0.0.0.0">
  18.     参数 服务器端口 <类型 = 整数 @默认值 = 8000>
  19.     {
  20.         如果 (服务器.状态 == HP状态.已经启动 || 服务器.状态 == HP状态.正在启动)
  21.         {
  22.             服务器.停止 ()
  23.             睡眠当前线程 (500)
  24.         }

  25.         服务器.端口 = 服务器端口
  26.         调试输出 ("等候队列大小 " + 到文本 (服务器.等候队列大小))
  27.         调试输出 ("最大投递数 " + 到文本 (服务器.最大投递数))
  28.         调试输出 ("通信缓冲区尺寸 " + 到文本 (服务器.通信缓冲区尺寸))
  29.         调试输出 ("内存缓存池尺寸 " + 到文本 (服务器.内存缓存池尺寸))
  30.         调试输出 ("连接缓存池尺寸 " + 到文本 (服务器.连接缓存池尺寸))


  31.         服务器.通信缓冲区尺寸 = 1024 * 1024 * 50  // 100M

  32.         调试输出 ("通信缓冲区尺寸 " + 到文本 (服务器.通信缓冲区尺寸))

  33.         返回 (服务器.启动 (服务器地址))
  34.     }

  35.     方法 HP_TCP服务器_数据进入 <接收事件 类型 = 整数 注释 = "  当服务器接收到客户端数据时,将触发本事件."
  36.             注释 = "  请注意,HP服务器/Pull服务器/Pack服务器收到数据后,都将会通过本事件通知用户," 注释 = "但不同的服务器将会导致本事件参数不同,请您按照以下方式进行数据接收."
  37.             注释 = "" 注释 = "    1.HP服务器: HP服务器为PUSH通信模型,接收到数据后,将会立即通过本事件通知用"
  38.             注释 = "户,并且设置本事件的"当前接收数据长度"和"当前所接收数据"参数." 注释 = ""
  39.             注释 = "    2.PULL服务器: Pull服务器接收到数据后,将会立即通过本事件通知用户,但是只会"
  40.             注释 = "设置本事件的"当前接收数据长度"参数,"当前所接收数据"将为空对象,您可以进行数"
  41.             注释 = "据长度累计,当所接收到数据长度为完整的包长度后,使用方法"抓取数据"或"窥探数据"" 注释 = "从内存中将数据提取,直接组成一个完整的数据包." 注释 = ""
  42.             注释 = "    3.Pack服务器: Pack服务器接收到数据后,并不会立即通过本事件通知用户,只有当数" 注释 = "据接收完整之后,才会触发本事件,省去您自行拆包组包的步骤."
  43.             返回值注释 = "本事件返回值无具体意义,请返回默认值0." 折叠 折叠2>
  44.     参数 来源对象 <类型 = HP_TCP服务器 注释 = "提供事件产生的具体来源对象">
  45.     参数 标记值 <类型 = 整数 注释 = "用户调用"挂接事件"命令时所提供的"标记值"参数值,非此方式挂接事件则本参数值固定为0.">
  46.     参数 当前数据来源连接ID <类型 = 整数 注释 = "当前连接ID">
  47.     参数 当前接收数据长度 <类型 = 整数 注释 = "当前数据长度">
  48.     参数 当前所接收数据 <类型 = "字节 []" 注释 = "当前所接收数据." 注释 = "请注意: 如果当前服务器为PULL服务器,本参数将为空对象,请不要使用本参数.">
  49.     {
  50.         如果 (来源对象 == 服务器)
  51.         {
  52.             // 调试输出 ("数据进入=====================")
  53.             如果 (取数组成员数 (当前所接收数据) < 4)
  54.             {
  55.                 // 防止空数据
  56.                 来源对象.断开连接 (当前数据来源连接ID)
  57.                 返回 (0)
  58.             }

  59.             如果 (字节数组到文本 (字节数组操作.取数组左边 (当前所接收数据, 4)) == "GET ")  // WS 握手协议
  60.             {
  61.                 变量 收到数据 <类型 = 文本型>
  62.                 收到数据 = 字节数组到文本 (当前所接收数据)
  63.                 // 检查是否为请求建立协议
  64.                 如果 (文本包含 (收到数据, "Sec-WebSocket-Key"))
  65.                 {
  66.                     变量 匹配器 <参考 类型 = 正则匹配器类>
  67.                     变量 请求密钥 <类型 = 文本型>
  68.                     变量 回复密钥 <类型 = 文本型>
  69.                     变量 回复内容 <类型 = 文本型>
  70.                     匹配器 = 正则表达式类.编译 ("(?<=Sec-WebSocket-Key: )[A-Za-z0-9+\\/=]+").创建匹配器 (收到数据)
  71.                     如果 (匹配器.查找下一个 ())
  72.                     {
  73.                         请求密钥 = 匹配器.取子匹配组 (0)
  74.                         // 组织回复密钥
  75.                         如果 (请求密钥 != "")
  76.                         {
  77.                             回复密钥 = Base64类.编码至文本 (加解密类.取数据SHA1_字节数组 (文本到字节数组 (请求密钥 + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11")), Base64编码标记.不换行)
  78.                             调试输出 ("回复密钥:" + 回复密钥)
  79.                             // 组织回复内容
  80.                             回复内容 = "HTTP/1.1 101 Switching Protocols" + "\r\n"
  81.                             回复内容 = 回复内容 + "Upgrade: websocket" + "\r\n"
  82.                             回复内容 = 回复内容 + "Connection: Upgrade" + "\r\n"
  83.                             回复内容 = 回复内容 + "Sec-WebSocket-Accept: " + 回复密钥 + "\r\n"
  84.                             回复内容 = 回复内容 + "Server: BM Server" + "\r\n"
  85.                             回复内容 = 回复内容 + "Access-Control-Allow-Headers: content-type" + "\r\n" + "\r\n"

  86.                             来源对象.发送数据 (当前数据来源连接ID, 文本到字节数组 (回复内容))
  87.                             客户进入 (当前数据来源连接ID)
  88.                         }
  89.                         否则
  90.                         {
  91.                             来源对象.断开连接 (当前数据来源连接ID)
  92.                             返回 (0)
  93.                         }
  94.                     }
  95.                     否则
  96.                     {
  97.                         来源对象.断开连接 (当前数据来源连接ID)
  98.                         返回 (0)
  99.                     }





  100.                 }
  101.             }
  102.             <折叠> 否则
  103.             {
  104.                 // 调试输出 (加解密类.字节数组到十六进制文本 (当前所接收数据))
  105.                 // 尝试解析WS数据协议
  106.                 变量 第一字节 <类型 = 文本型>
  107.                 变量 第二字节 <类型 = 文本型>
  108.                 第一字节 = 整数到二进制文本 (位与 (当前所接收数据 [0], 0xff))
  109.                 第二字节 = 整数到二进制文本 (位与 (当前所接收数据 [1], 0xff))

  110.                 // 调试输出 ("第一字节 " + 第一字节)
  111.                 // 调试输出 ("第二字节 " + 第二字节)

  112.                 如果 (取文本左边 (第一字节, 1) == "1")  // FIN 结束位,=1 即为最后一帧 ;目前缓存设置够大,无需分片,如有分片需求,需要完善分片组包代码
  113.                 {
  114.                     变量 操作码 <类型 = 整数>
  115.                     变量 掩码 <类型 = "字节 []" 值 = 空对象 注释 = "内容长度 后面 4 个字节为掩码;MASK=1时有效">
  116.                     操作码 = 进制_到整数 (取文本右边 (第一字节, 4))
  117.                     如果 (取文本左边 (第二字节, 1) != "1")
  118.                     {
  119.                         // 不接受 没有掩码加密 的数据
  120.                         返回 (0)
  121.                     }

  122.                     调试输出 ("FIN 操作码 " + 到文本 (操作码))

  123.                     <折叠> 如果 (操作码 == 1 || 操作码 == 2)  // 1  表示帧内容是纯文本   2  表示帧内容是二进制数据
  124.                     {
  125.                         // 掩码标志位"MASK":表示帧内容是否使用异或操作(xor)做简单的加密.目前的 WebSocket 标准规定,客户端发送数据必须使用掩码,而服务器发送则必须不使用掩码.
  126.                         变量 内容长度 <类型 = 整数>
  127.                         变量 内容开始位 <类型 = 整数>
  128.                         内容长度 = 进制_到整数 (取文本右边 (第二字节, 7))
  129.                         // 调试输出 ("内容长度 " + 到文本 (内容长度))
  130.                         如果 (内容长度 < 126)  // <=125直接表示 内容长度,无扩展
  131.                         {
  132.                             掩码 = 字节数组操作.取数组中间 (当前所接收数据, 2, 4)
  133.                             内容开始位 = 6
  134.                         }
  135.                         否则 (内容长度 == 126)  // 扩展 2 个字节为 内容长度
  136.                         {
  137.                             内容长度 = 进制_到整数 (加解密类.字节数组到十六进制文本 (字节数组操作.取数组中间 (当前所接收数据, 2, 2)), 16)
  138.                             掩码 = 字节数组操作.取数组中间 (当前所接收数据, 4, 4)
  139.                             内容开始位 = 8
  140.                         }
  141.                         否则 (内容长度 == 127)  // 扩展 8 个字节为 内容长度
  142.                         {
  143.                             内容长度 = 进制_到整数 (加解密类.字节数组到十六进制文本 (字节数组操作.取数组中间 (当前所接收数据, 2, 2)), 16)
  144.                             掩码 = 字节数组操作.取数组中间 (当前所接收数据, 10, 4)
  145.                             内容开始位 = 14
  146.                         }

  147.                         // 调试输出 ("内容长度 " + 到文本 (内容长度))
  148.                         // 调试输出 ("内容长度 " + 到文本 (取数组成员数 (当前所接收数据) - 内容开始位))
  149.                         // 调试输出 ("内容开始位 " + 到文本 (内容开始位))

  150.                         // 首先校验数据长度是否正确
  151.                         如果 (内容长度 != 取数组成员数 (当前所接收数据) - 内容开始位)
  152.                         {
  153.                             返回 (0)
  154.                         }
  155.                         // 校验掩码是否正确
  156.                         如果 (取数组成员数 (掩码) != 4)
  157.                         {
  158.                             返回 (0)
  159.                         }

  160.                         // 异或 出数据内容
  161.                         变量 数据内容 <类型 = "字节 []">
  162.                         变量 掩码位 <类型 = 整数 注释 = "使用哪儿个掩码进行 异或 运算,0-3 循环使用">
  163.                         变量 掩码数据 <类型 = "整数 [4]">
  164.                         计次循环 (4)  // 掩码是固定的 4 位长度
  165.                         {
  166.                             掩码数据 [取循环索引 ()] = 位与 (掩码 [取循环索引 ()], 0xff)
  167.                         }

  168.                         数据内容 = 字节数组操作.创建 (内容长度)
  169.                         计次循环 (内容长度)
  170.                         {
  171.                             如果 (掩码位 > 3)
  172.                             {
  173.                                 掩码位 = 0
  174.                             }

  175.                             数据内容 [取循环索引 ()] = (字节)位异或 (位与 (当前所接收数据 [内容开始位 + 取循环索引 ()], 0xff), 掩码数据 [掩码位])

  176.                             掩码位 = 掩码位 + 1
  177.                         }

  178.                         // 调试输出 ("收到内容 " + 字节数组到文本 (数据内容))
  179.                         如果 (操作码 == 1)
  180.                         {
  181.                             数据进入 (当前数据来源连接ID, 内容长度, 操作码, 字节数组到文本 (数据内容))
  182.                         }
  183.                         否则 (操作码 == 2)
  184.                         {
  185.                             数据进入 (当前数据来源连接ID, 内容长度, 操作码, 加解密类.字节数组到十六进制文本 (数据内容))
  186.                         }

  187.                     }
  188.                     否则 (操作码 == 8)  // 8  是关闭连接
  189.                     {
  190.                         // 掩码标志位"MASK":表示帧内容是否使用异或操作(xor)做简单的加密.目前的 WebSocket 标准规定,客户端发送数据必须使用掩码,而服务器发送则必须不使用掩码.
  191.                         变量 内容长度 <类型 = 整数>
  192.                         变量 内容开始位 <类型 = 整数>
  193.                         内容长度 = 进制_到整数 (取文本右边 (第二字节, 7))
  194.                         // 调试输出 ("内容长度 " + 到文本 (内容长度))
  195.                         如果 (内容长度 == 0)  // 0 字节(无状态码和原因)
  196.                         {
  197.                             来源对象.断开连接 (当前数据来源连接ID)
  198.                             返回 (0)
  199.                         }
  200.                         否则 (内容长度 < 126)  // <=125直接表示 内容长度,无扩展
  201.                         {
  202.                             掩码 = 字节数组操作.取数组中间 (当前所接收数据, 2, 4)
  203.                             内容开始位 = 6
  204.                         }
  205.                         否则 (内容长度 == 126)  // 扩展 2 个字节为 内容长度
  206.                         {
  207.                             内容长度 = 进制_到整数 (加解密类.字节数组到十六进制文本 (字节数组操作.取数组中间 (当前所接收数据, 2, 2)), 16)
  208.                             掩码 = 字节数组操作.取数组中间 (当前所接收数据, 4, 4)
  209.                             内容开始位 = 8
  210.                         }
  211.                         否则 (内容长度 == 127)  // 扩展 8 个字节为 内容长度
  212.                         {
  213.                             内容长度 = 进制_到整数 (加解密类.字节数组到十六进制文本 (字节数组操作.取数组中间 (当前所接收数据, 2, 2)), 16)
  214.                             掩码 = 字节数组操作.取数组中间 (当前所接收数据, 10, 4)
  215.                             内容开始位 = 14
  216.                         }

  217.                         // 调试输出 ("内容长度 " + 到文本 (内容长度))
  218.                         // 调试输出 ("内容长度 " + 到文本 (取数组成员数 (当前所接收数据) - 内容开始位))
  219.                         // 调试输出 ("内容开始位 " + 到文本 (内容开始位))

  220.                         // 首先校验数据长度是否正确
  221.                         如果 (内容长度 != 取数组成员数 (当前所接收数据) - 内容开始位)
  222.                         {
  223.                             返回 (0)
  224.                         }
  225.                         // 校验掩码是否正确
  226.                         如果 (取数组成员数 (掩码) != 4)
  227.                         {
  228.                             返回 (0)
  229.                         }

  230.                         // 异或 出数据内容
  231.                         变量 数据内容 <类型 = "字节 []">
  232.                         变量 掩码位 <类型 = 整数 注释 = "使用哪儿个掩码进行 异或 运算,0-3 循环使用">
  233.                         变量 掩码数据 <类型 = "整数 [4]">
  234.                         计次循环 (4)  // 掩码是固定的 4 位长度
  235.                         {
  236.                             掩码数据 [取循环索引 ()] = 位与 (掩码 [取循环索引 ()], 0xff)
  237.                         }

  238.                         数据内容 = 字节数组操作.创建 (内容长度)
  239.                         计次循环 (内容长度)
  240.                         {
  241.                             如果 (掩码位 > 3)
  242.                             {
  243.                                 掩码位 = 0
  244.                             }

  245.                             数据内容 [取循环索引 ()] = (字节)位异或 (位与 (当前所接收数据 [内容开始位 + 取循环索引 ()], 0xff), 掩码数据 [掩码位])
  246.                             掩码位 = 掩码位 + 1
  247.                         }

  248.                         // 取出 关闭帧 的在和结构(状态码 + 原因字符串)
  249.                         变量 状态码 <类型 = 整数 注释 = "1000:正常关闭(正常终止连接)." 注释 = "1001:终端离开(如浏览器关闭页面)." 注释 = "1008:消息违反协议(如格式错误)."
  250.                                 注释 = "1011:服务器内部错误.">
  251.                         状态码 = 进制_到整数 (加解密类.字节数组到十六进制文本 (字节数组操作.取数组左边 (数据内容, 2)), 16)
  252.                         如果 (状态码 == 1001)
  253.                         {
  254.                             来源对象.断开连接 (当前数据来源连接ID)
  255.                         }
  256.                         否则
  257.                         {
  258.                             // 原 帧 回复
  259.                             // 第一字节 = 整数到十六进制文本 (进制_到整数 (第一字节)) + 文本到大写(整数到十六进制文本 (进制_到整数 ("0" + 取文本右边 (第二字节, 7)))) + 加解密类.字节数组到十六进制文本 (数据内容)
  260.                             第一字节 = "88" + 文本到大写 (整数到十六进制文本 (进制_到整数 ("0" + 取文本右边 (第二字节, 7)))) + 加解密类.字节数组到十六进制文本 (数据内容)  // 首字节 88 是 断开帧 的固定头
  261.                             数据内容 = 加解密类.十六进制文本到字节数组 (第一字节)
  262.                             来源对象.发送数据 (当前数据来源连接ID, 数据内容)
  263.                         }

  264.                     }
  265.                     <折叠> 否则 (操作码 == 9)  // 9  是连接保活的 PING
  266.                     {

  267.                     }
  268.                     <折叠> 否则 (操作码 == 10)  // 10 是连接保活的 PONG
  269.                     {



  270.                     }


  271.                 }
  272.                 否则
  273.                 {
  274.                     来源对象.断开连接 (当前数据来源连接ID)
  275.                 }

  276.             }

  277.         }
  278.         返回 (0)
  279.     }

  280.     方法 发送数据 <公开 类型 = 逻辑型 折叠>
  281.     参数 连接ID <类型 = 整数 注释 = "当前连接ID">
  282.     参数 数据类型 <类型 = 整数 注释 = "1  表示帧内容是纯文本(二进制数据流建议转为Base64后发送,接收端解码)." 注释 = "8  是关闭连接."
  283.             注释 = "9  是连接保活的 PING.暂不支持" 注释 = "10 是连接保活的 PONG.暂不支持">
  284.     参数 数据内容 <类型 = 文本型 注释 = "关闭连接 时使用常量中的关闭码,如:WebSocket服务器.关闭码_正常关闭" @默认值 = "">
  285.     {
  286.         如果 (数据类型 == 1)  // 发送文本
  287.         {
  288.             如果 (数据内容 == "")
  289.             {
  290.                 返回 (假)
  291.             }

  292.             变量 发送内容 <类型 = "字节 []">
  293.             变量 内容长度 <类型 = 整数>
  294.             变量 内容数据 <类型 = 文本型 注释 = "待发送的十六进制文本">
  295.             发送内容 = 文本到字节数组 (数据内容)
  296.             内容长度 = 取数组成员数 (发送内容)
  297.             如果 (内容长度 < 126)  // 0-125:直接用 7 位表示
  298.             {
  299.                 返回 (服务器.发送数据 (连接ID, 加解密类.十六进制文本到字节数组 ("81" + 文本到大写 (整数到十六进制文本 (内容长度)) + 加解密类.字节数组到十六进制文本 (发送内容))))  // 首字节 81 是 文本帧 的固定头

  300.             }
  301.             否则 (内容长度 <= 65535)  // 126-65535:7 位设为 126,后跟 16 位长度
  302.             {
  303.                 内容数据 = 文本到大写 (整数到十六进制文本 (内容长度))
  304.                 判断循环 (取文本长度 (内容数据) < 4)
  305.                 {
  306.                     内容数据 = "0" + 内容数据  // 16 位长度为 2 个字节= 0xFF *2,需要4位(0xFFFF)
  307.                 }

  308.                 返回 (服务器.发送数据 (连接ID, 加解密类.十六进制文本到字节数组 ("81" + 文本到大写 (整数到十六进制文本 (126)) + 内容数据 + 加解密类.字节数组到十六进制文本 (发送内容))))  // 首字节 81 是 文本帧 的固定头

  309.             }
  310.             否则  // 大于 65535:7 位设为 127,后跟 64 位长度
  311.             {
  312.                 内容数据 = 文本到大写 (整数到十六进制文本 (内容长度))
  313.                 判断循环 (取文本长度 (内容数据) < 16)
  314.                 {
  315.                     内容数据 = "0" + 内容数据  // 64 位长度为 8 个字节= 0xFF *8,需要16位(0xFFFF)
  316.                 }

  317.                 返回 (服务器.发送数据 (连接ID, 加解密类.十六进制文本到字节数组 ("81" + 文本到大写 (整数到十六进制文本 (126)) + 内容数据 + 加解密类.字节数组到十六进制文本 (发送内容))))  // 首字节 81 是 文本帧 的固定头
  318.             }

  319.         }
  320.         否则 (数据类型 == 8)  // 主动关闭
  321.         {
  322.             服务器.发送数据 (连接ID, 加解密类.十六进制文本到字节数组 ("881C03E841637469766520636C6F73757265206F66207468652075736572"))
  323.             返回 (服务器.断开连接 (连接ID))

  324.         }
  325.         返回 (假)
  326.     }

  327.     方法 数据进入 <公开 定义事件 类型 = 整数 注释 = "  当服务器接收到客户端数据时,将触发本事件." 返回值注释 = "本事件返回值无具体意义,请返回默认值0." 折叠>
  328.     参数 连接ID <类型 = 整数 注释 = "当前连接ID">
  329.     参数 数据长度 <类型 = 整数 注释 = "当前数据长度">
  330.     参数 数据类型 <类型 = 整数 注释 = "当前数据类型:1 表示帧内容是纯文本,2 表示帧内容是二进制数据(十六进制文本)">
  331.     参数 数据内容 <类型 = 文本型 注释 = "当前所接收数据." 注释 = "请注意: 如果当前服务器为PULL服务器,本参数将为空对象,请不要使用本参数.">

  332.     方法 客户进入 <公开 定义事件 类型 = 整数 注释 = "  当服务器接收到客户端握手请求并握手成功后,将触发本事件." 返回值注释 = "本事件返回值无具体意义,请返回默认值0." 折叠>
  333.     参数 连接ID <类型 = 整数 注释 = "当前连接ID">

  334.     方法 客户离开 <公开 定义事件 类型 = 整数 注释 = "  当服务器与客户端断开后,将触发本事件." 返回值注释 = "本事件返回值无具体意义,请返回默认值0." 折叠>
  335.     参数 连接ID <类型 = 整数 注释 = "当前连接ID">

  336.     方法 进制_到整数 <公开 静态 类型 = 整数 注释 = "本方法可将 X进制文本转换成十进制整数" 返回值注释 = "返回整数" 折叠 @嵌入式方法 = "">
  337.     参数 参_文本 <类型 = 文本型 注释 = "提供十六进制文本">
  338.     参数 进制数 <类型 = 整数 注释 = "提供参数 进制数 2-36" @默认值 = 2>
  339.     {
  340.         @ Integer.parseInt(@<参_文本>, @<进制数>)
  341.     }

  342.     方法 HP_TCP服务器_客户离开 <接收事件 类型 = 整数 注释 = "  当客户端断开服务器后,将触发本事件." 注释 = "  请注意:当本事件被触发后,服务器将会从连接ID队列中删除该连接ID,"
  343.             注释 = "之后您将不可继续操作此连接ID." 返回值注释 = "本事件返回值无具体意义,请返回默认值0." 折叠>
  344.     参数 来源对象 <类型 = HP_TCP服务器 注释 = "提供事件产生的具体来源对象">
  345.     参数 标记值 <类型 = 整数 注释 = "用户调用"挂接事件"命令时所提供的"标记值"参数值,非此方式挂接事件则本参数值固定为0.">
  346.     参数 当前离开客户ID <类型 = 整数 注释 = "当前离开服务器的连接ID">
  347.     参数 客户断开原因 <类型 = 整数 注释 = "当前客户断开服务器原因">
  348.     参数 客户端断开错误码 <类型 = 整数 注释 = "如果断开原因非">
  349.     {
  350.         如果 (来源对象 == 服务器)
  351.         {
  352.             客户离开 (当前离开客户ID)
  353.         }
  354.         返回 (0)
  355.     }
  356. }
复制代码


0o雪中情o0
三人行,必有我师焉
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|递归火山软件开发平台 ( 鄂ICP备18029190号 )

GMT+8, 2025-9-26 07:43 , Processed in 0.081863 second(s), 19 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表