migangel

关注 40 粉丝 26 小组 83
真诚 大爱 我存在!

人人都是产品汪

基于WebSocket双屏互动体验

项目背景:

移动互联网时代的悄然来袭已经不断改变着我们的生活方式和体验模式,移动端的页面交互形式也日新月异,这次为了配合《斗战诛天》的品牌宣传,和在上海举行的落地活动,我们在需求交互形式上采用了全新的双屏互动体验模式。该需求主要以“营救悟空“为主题,用户通过扫描二维码将手机与PC屏幕进行连接,跟随游戏提示,通过游戏中三大种族角色扮演打破锁链营救悟空,让玩家深度体验《斗战诛天》“聚族相交、族宰西游”的创新剧情。

以图集形式查看 >>

双屏互动原理描述:

现在多数双屏互动的实现方式主要是依靠浏览器的WebSocket即时通信技术,包括国外许多案例,在以前传统的网站为了实现这种技术基本都是轮询,在一个特定的时间内,由客户端向服务端发出请求,之后服务器返回到浏览器,这种传统的实现方法需要客户端不停的向服务端请求数据,而且其传输的数据可能是一个很小的值。

在 WebSocket API中,浏览器和服务器只需要要做一个握手的动作,然后浏览器和服务器之间就形成了一条快速通道,两者之间就可以直接实时的互相传送数据。

采用websocket技术的页面不同于普通页面,而是需要特殊的服务器环境支持。 

服务器环境的搭建:

目前支持WebSocket环境有很多方式,比如PHP、Java、.Net、Tomcat、Nodejs等,还有html5 的websocket方案,但是目前在我国浏览器使用情况上,IE用户还占有50%左右的市场份额,html5 的websocket只能支持IE10+和其他高端浏览器,在兼容性方面socket.io做的很好,所以对于前端工程师,我们优先选Nodejs和socket.io来搭建WebSocket服务器端。

浏览器支持情况
Chrome4+
Firefox4+
IE10+
Opera10+
Safari5+

浏览器对 HTML5 WebSocket 的支持情况

前期我们可以在自己电脑搭建与服务器一致的环境来测试,本地搭建的方法:

  • 1. 下载官方Node.js,安装可以一直下一步,我个人习惯都会自定义安装软件

  • 2. 安装Nodejs 的模块管理器npm(官网最新版Nodejs已集成,无需单独安装)

  • 3. 命令窗口模式安装 socket.io(npm install socket.io)

    (这里如果遇到安装不成功情况,注意考虑设置一下代理,设置方法:npm config set proxy=地址:端口号,运气实在不好的话从其他电脑复制同版本文件夹也一样)

  • 4. 最后查看安装的模块及版本:npm list

    以图集形式查看 >>

说到npm管理器,这里列一下几个常用的npm命令:

  • npm -v 查看当前npm的版本

  • npm list 查看安装的模块及版本

  • npm install name安装需要nodejs依赖的模块

  • npm root 查看当前包安装路径

  • npm update name 更新某个模块

  • npm help 帮助

也有很多案例结合nodejs的web框架express来构建http服务器,本次案例中没有使用这种方案,所以这里也不做详细阐述。到此本地环境就已经搭建好,是不是很简单==

Tips:可以在电脑-附件-把cmd命令提示符发送到桌面,右键“属性-快捷方式-起始位置”设置成自己的nodejs安装目录,这样在后面本地调试demo的时候,每次启动命令窗口就不用cd定位nodejs目录。还可以给电脑设置环境变量到安装目录,这样也可以达到不用每次都定位文件夹。

项目逻辑设计

其实本次活动需求逻辑不是很复杂,我的大致流程是:

  • 1. 从PC端页面入口,与服务器app链接,获取一个身份标识,该身份每次刷新页面都随机生成

  • 2. 移动端页面通过获取到PC端的随机身份生成的随机二维码,就同样可以获取PC端的那个标识

  • 3. 扫描二维码的过程就是与服务器进行连接,判断它获取的身份标识与PC生成的标识是否一致,ok的话链接成功,继续下一步发送和接收数据

    以图集形式查看 >>

Socket发送与接收数据简单demo如下:

PC端和移动端都引入:/socket/socket.io.js,大家在使用这个文件的时候,会发现这个路径在本地没这个文件,但是能够正常工作,查看网上有人说是在请求这个文件时会重定向,在实际工作当中使用静态地址也是可行的。

PC客户端刷新页面之后触发socket.io当中的内置事件“connection”,连接之后调用带socketc参数的回调函数。当中比较关键的函数emit和on,其中的事件名是可以自定义,只要不和内置事件相冲突。

移动端

var socket = io.connect("http://127.0.0.1:8080"); socket.emit("MobileToPC","Data From mobile!"); socket.on("ReceiveDataToMobile",function(data){ console.log(data) }) socket.on("disconnect", function(){ alert("链接断开,请刷新页面!")  });

服务端

var http= require("http"), io= require("socket.io"); var app = http.createServer(), io = io.listen(app); app.listen(8080); io.sockets.on("connection", function(socket){ socket.on("MobileToPC",function(data){ console.log(data);//服务端输出打印 socket.broadcast.emit("SendDataToPC",data); }); socket.on("PCToMobile",function(data){ console.log(data); socket.broadcast.emit("ReceiveDataToMobile",data); }); });

PC端

var socket = io.connect("http://127.0.0.1:8080"); socket.on("SendDataToPC", function (data){  console.log(data) }) function SendData(){ socket.emit("PCToMobile","Data From PC!"); } socket.on("disconnect", function(){ alert("链接断开!") });

以上是一个非常简单的接收和发送数据的demo,从上面可以看出,我们在移动端发送了“MobileToPC”事件,在服务器接收了该事件中的数据“Data From mobile!”,并且打印输出,之后发送给PC端,所以PC端接收后打印出该data数据(Data From mobile!),PC端发送也一样。运行很简单,在命令窗口下定位到nodejs安装目录运行:node app.js,打开客户端页面就可以看见效果。

我们的项目就是在就在此用法上增加逻辑判断,包括用户身份的标识,一对一的发送和接收数据。

首次做该类跨屏需求,我们遇到如下一些问题:

问题:身份判断问题

var clients=[]; ……………… clients.push({code:userid,socket:this}); ……………… var removeFromArr = function(arr, id){ var tempArr = []; arr.forEach(function(v, i){ if(v.code != id){ tempArr.push(v); } }) return tempArr; } socket.on("disconnect",function(){ clients = removeFromArr(clients, socket.id); });

本文前面提到使用的随机标识,该标识我使用PC端生成的socket.id,每次生成的这个身份都存在服务端的一个数组中,在移动端和发送数据时候去比较两者之间是不是一一对应,每次客户端在退出或者断开连接时利用“disconnect”来清除socket.id释放更多资源,可是如果项目同时在线人数巨大的时候,服务器压力会比较大。该方法在虽然不影响项目使用,但是还是有可改进的地方

可优化的方法:经过网上许多文章提到socket.io可以利用socket.join(“your room name”)进入一个房间,相当于一个命名空间,可以对一个特定的房间(同一个分组传输消息)广播,而不影响在其他房间或不在房间的成员

socket.on("roomA", function (data) { socket.join("roomA");}); socket.on("roomB",function(data){ socket.join("roomB");}); ……………… socket.to("roomA").emit("event_name", data); io.sockets.in("roomA").emit("event_name", data);

问题:控制台出现socket.io is not allowed by Access-Control-Allow-Origin 跨域问题

通过网上搜索和咨询其他同学得知,增加 headers['Access-Control-Allow-Origin'] = "*";google上也提到还有可能是版本冲突,该问题目前还没很好的解决方法。

问题:app进程管理

对于socket,需要一直运行进程App,假如进程有问题出现断开的时候,我们都要人工重启App。所以可以考虑使用forever来管理App应用,它可以通过monitor来监控node进程的运行情况,一旦出现问题可以自动重启,保证我们线上项目正常运行。

下图是PC端和移动端对应的效果,移动端页面是由之前“山里人的大海之旅”的作者完成的页面前端,从下图可以看出,用户在操作的每一步操作都会有细心的提示,是不是交互体验很不错!

以图集形式查看 >>

 

以图集形式查看 >>

 

以图集形式查看 >>

 

以图集形式查看 >>

 

项目结语:本次项目组首次运用跨屏互动的创新形式来进行线下落地活动,多少会担心项目的使用,包括如果玩家没有连接成功时候,在移动端是可以继续参加活动体验的,在这种创新型活动当时,前期做好充分的时间来应对我们没有遇到过的问题很有必要,也应该像本次项目一样,为自己的项目预留一些备选方案使得活动继续进行。在活动落地之后,移动端页面还在需要继续优化,通过不同类型的移动设备给予不同的体验效果。

以上就是本人首次尝试跨屏互动需求的一点分享,有任何不妥之处请大家多多包涵。

最后附上本次《斗战诛天》双屏互动地址: http://zt.qq.com/act/hdz/index.htm




0

深有同感

0

抱抱

0

呵呵

0

沟通无望

0

0 个产品汪表达了自己的情绪

这里有 0个讨论,你怎么看?

 

请先登录,参与讨论

获得“隐君子”勋章才可以戴面具哦!去 获取该勋章

下一篇:如何在网络上创造一个人?

猜你喜欢

  • 【好好活着小姐】五月入夏 好物伴我度过温馨母亲节
    【好好活着小姐】五月入夏 好物伴我度过温馨母亲节
    2095浏览184关注
  • 【陌上花开】~~~初夏护肤进行时,好用单品逐个数~~~
    【陌上花开】~~~初夏护肤进行时,好用单品逐个数~~~
    2076浏览168关注
  • 【Rubyの爱用品】敏感患者-----五月小清新爱用品
    【Rubyの爱用品】敏感患者-----五月小清新爱用品
    1657浏览217关注
  • 【Rubyの爱用品】雅漾小金刚防晒让我爱上夏天
    【Rubyの爱用品】雅漾小金刚防晒让我爱上夏天
    12573浏览238关注

小组动态

  • 【阿柚柚】PG霜、肌底液、VC精华,坏天气也要有好肌肤!
    【阿柚柚】PG霜、肌底液、VC精华,坏天气也要有好肌肤!
    1561浏览130关注
  • 【杏仁儿1201】百元内解决尴尬问题
    【杏仁儿1201】百元内解决尴尬问题
    23490浏览133关注
  • 【夏雪】抵抗雾霾防敏感,四款法国药妆喷雾大比拼
    【夏雪】抵抗雾霾防敏感,四款法国药妆喷雾大比拼
    6321浏览0关注
  • 【Rubyの爱用品】雅漾小金刚防晒让我爱上夏天
    【Rubyの爱用品】雅漾小金刚防晒让我爱上夏天
    12571浏览238关注