研究SPICE,找到了他们官方指定的HTML5客户端。
下载下来用一下,发现跟网页VNC的水平差不多了。
http://www.spice-space.org/page/Html5

服务端直接用QEMU起了一个WINDOWS XP,设定SPICE、再启动一个websockify。
但是一连上就发现鼠标不正常,反映总比实际的距离短。

于是看了下源码,鼠标支持两种模式:
模式1是客户端向服务器发出消息,告诉他鼠标移动了多少。
模式2是客户端向服务器发出消息,告诉他鼠标的具体位置。

追踪了一个,发现SPICE-HTML5最终和QEMU协商为模式1,然后打开inputs.js,发现这么一段代码。
0123456789101112131415161718192021

if (this.sc.mouse_mode == SPICE_MOUSE_MODE_CLIENT)
{
    move = new SpiceMsgcMousePosition(this.sc, e)
    msg.build_msg(SPICE_MSGC_INPUTS_MOUSE_POSITION, move);
}
else
{
    move = new SpiceMsgcMouseMotion(this.sc, e)
    msg.build_msg(SPICE_MSGC_INPUTS_MOUSE_MOTION, move);
}
if (this.sc && this.sc.inputs && this.sc.inputs.state === "ready")
{
    if (this.sc.inputs.waiting_for_ack < (2 * SPICE_INPUT_MOTION_ACK_BUNCH))
    {
        this.sc.inputs.send_msg(msg);
        this.sc.inputs.waiting_for_ack++;
    }
    else
    {
        DEBUG > 0 && this.sc.log_info("Discarding mouse motion");
    }
}

基本可以确定就是无论模式一还是模式2,都先生成消息,然后再发给服务器。
但是在发送之前有个检测
01234

if (this.sc.inputs.waiting_for_ack < (2 * SPICE_INPUT_MOTION_ACK_BUNCH))
{
    this.sc.inputs.send_msg(msg);
    this.sc.inputs.waiting_for_ack++;
}

貌似是“如果还在等待反馈(阈值之前),就先不发送”。
没仔细看SpiceMsgcMouseMotion,但是我做个VNC的网页客户端,做一个队列来缓存事件是常有的,如果不做队列,那么必须要记录下上一次发送消息时的状态。因此我猜测这个地方很有可能在SpiceMsgcMouseMotion里面有个状态记录上一次鼠标状态,如果这个消息被丢弃,那么就会丢弃一个鼠标移动事件。
代码整体改写如下:
0123456789101112131415161718192021

if (this.sc && this.sc.inputs && this.sc.inputs.state === "ready")
{
    if (this.sc.inputs.waiting_for_ack < (2 * SPICE_INPUT_MOTION_ACK_BUNCH))
    {
        if (this.sc.mouse_mode == SPICE_MOUSE_MODE_CLIENT)
        {
            move = new SpiceMsgcMousePosition(this.sc, e)
            msg.build_msg(SPICE_MSGC_INPUTS_MOUSE_POSITION, move);
        }
        else
        {
            move = new SpiceMsgcMouseMotion(this.sc, e)
            msg.build_msg(SPICE_MSGC_INPUTS_MOUSE_MOTION, move);
        }
        this.sc.inputs.send_msg(msg);
        this.sc.inputs.waiting_for_ack++;
    }
    else
    {
        DEBUG > 0 && this.sc.log_info("Discarding mouse motion");
    }
}

试了一下,完美运行。。。

最新文章

  1. 程序猿都没对象,JS竟然有对象?
  2. oracle 数据库Cmd命令导入导出
  3. 在jQuery ajax中按钮button和submit的区别分析
  4. 【BZOJ-1030】文本生成器 AC自动机 + DP
  5. NodeJS学习:爬虫小探补完计划
  6. 分析java.lang.NullPointerException thrown in RelativeLayout measure()
  7. 带你走近AngularJS 之创建自定义指令
  8. [转载]Web前端和后端之区分,以及面临的挑战【转】
  9. NPOI 1.2 教程
  10. CSS中的背景、雪碧图、超链接的伪类样式
  11. TeamCity Agent安装
  12. c/c++保存日志程序模板
  13. java使用document解析xml文件
  14. Jmeter进阶篇之保存测试结果
  15. 2017年蓝桥杯省赛A组c++第5题(递归算法填空)
  16. Js_protoType_原型
  17. 成对使用new和delete,传值传引用
  18. asp.net获取当前网址url
  19. GC那些事儿--Android内存优化第一弹
  20. 还没被玩坏的robobrowser(2)——安装及快速开始

热门文章

  1. AJAX路径问题
  2. 尚观Linux最佳入门高清视频教程033/133/253
  3. qq截图原理
  4. ASP.NET Core MVC 2.x 全面教程_ASP.NET Core MVC 12. Views 下
  5. Win32控制台程序和Win32应用程序
  6. 使用PDO操作数据库的好处
  7. python iteration 迭代
  8. mybaits 连接数据库汉字保存乱码??
  9. Caffe实战三(依赖包解析及环境配置)
  10. 题解报告:poj 1985 Cow Marathon(求树的直径)