查看: 3977|回复: 4

[原创发布] 在RM中使用websocket

[复制链接]
梦石
1
星屑
24088
在线时间
3339 小时
注册时间
2011-7-8
回帖
3862

开拓者

发表于 2018-11-25 17:09:52 | 显示全部楼层 |阅读模式

加入我们,或者,欢迎回来。

您需要 登录 才可以下载或查看,没有账号?注册会员

×
本帖最后由 guoxiaomi 于 2018-12-27 15:52 编辑

MV本来就是浏览器,原生支持websocket,但是 XP/VX/VA 目前没有看到类似的东西。这里就提供一个吧。

来自 github 上的 https://github.com/dhbaird/easywsclient,MIT Lisenece。据说作者写的时候没考虑到有人会在windows下用g++编译,所以“找了”大神帮忙修改了一点点,最后的源代码如下:
20181227-websocket.zip (374.9 KB, 下载次数: 114)

2018/12/27 更新3:
1. 解决了无法正常关闭 websocket 连接的问题
2. 提供了有限功能的XP范例,见 4 楼

2018/11/26 更新2:
1. 现在可以同时开启多个 websocket 连接,测试代码见 main.rb
2. update同时返回 总字符串长度 * 1024 + 接受的信息条数,从而同时得到这两个数据
3. ws_data 不需要接受参数,会获取前一个 ws_update(index) 返回的数据
2018/11/26 更新:解决了之前版本丢包问题

其中 main.cpp 是我自己随便写的封装。编译:
  1. g++ .\main.cpp .\easywsclient.cpp -shared -lws2_32 -o websocket.dll
复制代码

将 libgcc_s_dw2-1.dll 和 libstdc++-6.dll 一起附上了
发现还要 libwinpthread-1.dll
下面是测试代码,ws_url 里是一个 echo 服务器:
[pre lang="ruby"]ws_url = "ws://demos.kaazing.com/echo"

DLL_PATH = "../websocket.dll"

WS_CONNECT = Win32API.new(DLL_PATH, "ws_connect", "ip", "i")
WS_UPDATE = Win32API.new(DLL_PATH, "ws_update", "i", "i")
WS_DATA = Win32API.new(DLL_PATH, "ws_data", "pp", "v")
WS_SEND = Win32API.new(DLL_PATH, "ws_send", "ip", "v")
WS_CLOSE = Win32API.new(DLL_PATH, "ws_close", "i", "v")

raise if WS_CONNECT.call(0, ws_url) < 0

f = File.open("../result.txt", "w")

30.times do |i|
  WS_SEND.call(0, "hi! #{i}")
end

120.times do |i|
  Graphics.update

  n = WS_UPDATE.call(0)
  buffer_len = n / 1024
  recv_num = n % 1024

  if recv_num > 0
    buffer = "\0" * buffer_len
    lens = "\0" * 4 * recv_num

    WS_DATA.call(buffer, lens)

    s = 0
    f.puts "recv #{recv_num} at frame No.#{i}:"
    lens.unpack("L*").each do |len|
      f.puts "#{buffer[s...s + len]}"
      s += len
    end
  end
end

WS_CLOSE.call(0)

f.close

exit
[/pre]

生成结果,注意到 websocket 会一口气收到大量信息,并且顺序可能是乱序的,其实跟网速什么的有关系:
[pre lang="ruby"]recv 15 at frame No.9:
hi! 0
hi! 1
hi! 2
hi! 3
hi! 4
hi! 5
hi! 6
hi! 7
hi! 8
hi! 9
hi! 10
hi! 11
hi! 12
hi! 13
hi! 14
recv 15 at frame No.17:
hi! 15
hi! 16
hi! 17
hi! 18
hi! 19
hi! 20
hi! 21
hi! 22
hi! 23
hi! 24
hi! 25
hi! 26
hi! 27
hi! 28
hi! 29
[/pre]

评分

参与人数 1赞 +1 收起 理由
张咚咚 + 1 精品文章

查看全部评分

熟悉rgss和ruby,xp区版主~
正在填坑:《膜拜组传奇》讲述膜拜组和学霸们的故事。
已上steam:与TXBD合作的Reformers《变革者》
* 战斗调用公共事件 *
* RGSOS 网络脚本 *
梦石
2
星屑
13779
在线时间
2319 小时
注册时间
2011-6-4
回帖
586
发表于 2018-11-25 19:11:16 | 显示全部楼层
Wow,用这个是不是可以直接在游戏里连入Lofter或百度网盘下载页之类的

点评

你说的这些用HTTP就行了……  发表于 2018-11-25 20:05
BUG反馈请加QQ 529283039
水友群 917854767

回复

使用道具 举报

头像被屏蔽
梦石
0
星屑
653
在线时间
3774 小时
注册时间
2011-2-26
回帖
1577

开拓者

发表于 2018-11-28 20:43:38 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
签名被屏蔽
回复

使用道具 举报

梦石
1
星屑
24088
在线时间
3339 小时
注册时间
2011-7-8
回帖
3862

开拓者

 楼主| 发表于 2018-12-27 15:51:23 | 显示全部楼层
2018/12/27 更新
由于决定写一个VA的范例,所以这个XP的范例就直接发出来给大家交流吧
client.zip (1 MB, 下载次数: 87)
详情见main.rb:
1. 在创建 Network_Base 对象($net)后,不停的调用 $net.update,后台会自动尝试注册、登录、同步数据
2. 可以加入任意的群组,范例中是 test,访问 http://rgssser.applinzi.com/group.php?gid=test 查看共享的数据
3. Network_Base::listen 方法设置回调,当后台检测到特定的key值变化时,会调用回调的Proc
4. 文件上传、下载
5. 已在XP虚拟机中成功运行,如果是中文目录,就要把脚本拷贝到F11编辑器里

此外:
1. 每一个用户的用户群组是 u-1,u-2 这种形式,此群组是(假装)被密码保护的
2. 以 _ 开头的群组,会在所有人退出后销毁全部数据,删除全部文件
3. 群组 server 会记录有多少人已经注册了
4. 访问 http://rgssser.applinzi.com/clear.php?gid=test 删除群组里的变量,设置 gid=all 会清除所有数据
5. 下载不存在的文件会报错,懒得改了
6. 只有在 Group_Keys 中设置的变量、状态才会被后台处理,其他的信息即使收到了也会忽略

由于只是范例,未作任何的安全设置。
熟悉rgss和ruby,xp区版主~
正在填坑:《膜拜组传奇》讲述膜拜组和学霸们的故事。
已上steam:与TXBD合作的Reformers《变革者》
* 战斗调用公共事件 *
* RGSOS 网络脚本 *
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

Powered by Discuz! X5.0 © 2001-2026 Discuz! Team.

在本版发帖返回顶部