Project1

标题: 在RM中使用websocket [打印本页]

作者: guoxiaomi    时间: 2018-11-25 17:09
标题: 在RM中使用websocket
本帖最后由 guoxiaomi 于 2018-12-27 15:52 编辑

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

来自 github 上的 https://github.com/dhbaird/easywsclientMIT 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 服务器:
RUBY 代码复制
  1. ws_url = "ws://demos.kaazing.com/echo"
  2.  
  3. DLL_PATH = "../websocket.dll"
  4.  
  5. WS_CONNECT = Win32API.new(DLL_PATH, "ws_connect", "ip", "i")
  6. WS_UPDATE = Win32API.new(DLL_PATH, "ws_update", "i", "i")
  7. WS_DATA = Win32API.new(DLL_PATH, "ws_data", "pp", "v")
  8. WS_SEND = Win32API.new(DLL_PATH, "ws_send", "ip", "v")
  9. WS_CLOSE = Win32API.new(DLL_PATH, "ws_close", "i", "v")
  10.  
  11. raise if WS_CONNECT.call(0, ws_url) < 0
  12.  
  13. f = File.open("../result.txt", "w")
  14.  
  15. 30.times do |i|
  16.   WS_SEND.call(0, "hi! #{i}")
  17. end
  18.  
  19. 120.times do |i|
  20.   Graphics.update
  21.  
  22.   n = WS_UPDATE.call(0)
  23.   buffer_len = n / 1024
  24.   recv_num = n % 1024
  25.  
  26.   if recv_num > 0
  27.     buffer = "\0" * buffer_len
  28.     lens = "\0" * 4 * recv_num
  29.  
  30.     WS_DATA.call(buffer, lens)
  31.  
  32.     s = 0
  33.     f.puts "recv #{recv_num} at frame No.#{i}:"
  34.     lens.unpack("L*").each do |len|
  35.       f.puts "#{buffer[s...s + len]}"
  36.       s += len
  37.     end
  38.   end
  39. end
  40.  
  41. WS_CLOSE.call(0)
  42.  
  43. f.close
  44.  
  45. exit


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

作者: 真·可乐    时间: 2018-11-25 19:11
Wow,用这个是不是可以直接在游戏里连入Lofter或百度网盘下载页之类的
作者: 晴兰    时间: 2018-11-28 20:43
提示: 作者被禁止或删除 内容自动屏蔽
作者: guoxiaomi    时间: 2018-12-27 15:51
2018/12/27 更新
由于决定写一个VA的范例,所以这个XP的范例就直接发出来给大家交流吧
client.zip (1 MB, 下载次数: 89)
详情见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 中设置的变量、状态才会被后台处理,其他的信息即使收到了也会忽略

由于只是范例,未作任何的安全设置。




欢迎光临 Project1 (https://rpg.blue/) Powered by Discuz! X3.1