通过Node.js和Socket.io来实现手机的远程控制

Posted 凯凯而谈

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了通过Node.js和Socket.io来实现手机的远程控制相关的知识,希望对你有一定的参考价值。


用手机来实现远程控制是不是很酷?你不需要去写一个APP应用来实现这种功能-现在的手机浏览器已经支出了web socket技术,这提供了很多的可能。

这篇文章我们将用Node.js和[Socket.io](http://socket.io/)来实现手机控制PC的效果。


我们不必到处寻找基于html5的这种应用库。我们将使用[Reveal.js](https://github.com/hakimel/reveal.js/)-它来处理幻灯片动画效果,并支持键盘和触摸事件。


我们不必自己来实现远程控制的接口,我们将实现手机和电脑的同步。这样不仅能控制进度,也能同步的显示在你的手机上。


实现思路


技术上很简单。Reveal.js让当前的幻灯片序号在URL的hash上(e.g. `http://example.com/#/1`).我们将这个hash发送到所有连接的设备上,

对应的将会根据这个hash来自动的显示响应幻灯片。这样的话,别人可以方便的直接通过url来直接访问到显示的页面,所有我们需要输入一个验证码

在连接之前进行验证。


要说的是Reveal.js已经有一套API,我们可以直接调用来同步。但是hash变化的技术很简单,我们可以直接来实现。



运行


你可以本地运行示例,或者部署到能提供node.js环境的服务器上。本地运行更简单些,但是必须本地有node.js并执行`npm install`.


运行本地代码


* 下载示例代码

* 确保本地已经安装node.js。如果没有,请安装

* 解压刚才下载的代码包

* 打开终端进入相应的文件夹

* 运行`npm install`来安装依赖包

* 运行`node app.js`来启动应用

* PC端在浏览器打开`http://localhost:8080`,并输入连接码(默认是`kittens`)

* 在手机端浏览器打开`http://<your computer’s local ip address> `,并输入连接码

* 请享受


代码


思路说完,让我们来看看代码。这主要涉及2个js文件-app.js服务端控制,script.js浏览器端。你可以运行这个应用在Node.js 1.10+或者io.js.


后端,我们用到了[express](http://expressjs.com/)和[Socket.io](http://socket.io/).它主要用来响应socket.io的事件监听。用[express.static](http://expressjs.com/guide/using-middleware.html#middleware.built-in)来让public下的文件可以访问到。

`public/index.html`文件保护显示的代码。express.static将会让它自动显示,所以我们不需要`/`来路由。


`app.js`


// This is the server-side file of our mobile remote controller app.

// It initializes socket.io and a new express instance.

// Start it by running 'node app.js' from your terminal.



// Creating an express server


var express = require('express'),

app = express();


// This is needed if the app is run on heroku and other cloud providers:


var port = process.env.PORT || 8080;


// Initialize a new socket.io object. It is bound to

// the express app, which allows them to coexist.


var io = require('socket.io').listen(app.listen(port));



// App Configuration


// Make the files in the public folder available to the world

app.use(express.static(__dirname + '/public'));



// This is a secret key that prevents others from opening your presentation

// and controlling it. Change it to something that only you know.


var secret = 'kittens';


// Initialize a new socket.io application


var presentation = io.on('connection', function (socket) {


// A new client has come online. Check the secret key and

// emit a "granted" or "denied" message.


socket.on('load', function(data){


socket.emit('access', {

access: (data.key === secret ? "granted" : "denied")

});


});


// Clients send the 'slide-changed' message whenever they navigate to a new slide.


socket.on('slide-changed', function(data){


// Check the secret key again


if(data.key === secret) {


// Tell all connected clients to navigate to the new slide


presentation.emit('navigate', {

hash: data.hash

});

}

});

});


console.log('Your presentation is running on http://localhost:' + port);


下面是前端的js文件,将监听[hashchange](https://developer.mozilla.org/en-US/docs/Web/Events/hashchange)事件,并发送`socket.io`消息到服务器端。


`public/assets/js/script.js`


$(function() {


// Apply a CSS filter with our blur class (see our assets/css/styles.css)


var blurredElements = $('.homebanner, div.reveal').addClass('blur');


// Initialize the Reveal.js library with the default config options

// See more here https://github.com/hakimel/reveal.js#configuration


Reveal.initialize({

history: true // Every slide will change the URL

});


// Connect to the socket


var socket = io();


// Variable initialization


var form = $('form.login'),

secretTextBox = form.find('input[type=text]');


var key = "", animationTimeout;


// When the page is loaded it asks you for a key and sends it to the server


form.submit(function(e){


e.preventDefault();


key = secretTextBox.val().trim();


// If there is a key, send it to the server-side

// through the socket.io channel with a 'load' event.


if(key.length) {

socket.emit('load', {

key: key

});

}


});


// The server will either grant or deny access, depending on the secret key


socket.on('access', function(data){


// Check if we have "granted" access.

// If we do, we can continue with the presentation.


if(data.access === "granted") {


// Unblur everything

blurredElements.removeClass('blurred');


form.hide();


var ignore = false;


$(window).on('hashchange', function(){


// Notify other clients that we have navigated to a new slide

// by sending the "slide-changed" message to socket.io


if(ignore){

// You will learn more about "ignore" in a bit

return;

}


var hash = window.location.hash;


socket.emit('slide-changed', {

hash: hash,

key: key

});

});


socket.on('navigate', function(data){


// Another device has changed its slide. Change it in this browser, too:


window.location.hash = data.hash;


// The "ignore" variable stops the hash change from

// triggering our hashchange handler above and sending

// us into a never-ending cycle.


ignore = true;


setInterval(function () {

ignore = false;

},100);


});


}

else {


// Wrong secret key


clearTimeout(animationTimeout);


// Addding the "animation" class triggers the CSS keyframe

// animation that shakes the text input.


secretTextBox.addClass('denied animation');


animationTimeout = setTimeout(function(){

secretTextBox.removeClass('animation');

}, 1000);


form.show();

}


});


});


现在是幻灯片放映时间


手机远程访问控制已经可以了。希望你能从中得到有趣的体验。



参考:


`http://tutorialzine.com/2015/02/smartphone-remote-control-for-presentations/`

`https://github.com/hakimel/reveal.js/wiki/Example-Presentations`




以上是关于通过Node.js和Socket.io来实现手机的远程控制的主要内容,如果未能解决你的问题,请参考以下文章

STOMP 上的重复事件 Socket.io 和 Node.js

node.js、socket.io 和 SSL

使用node.js实现多人聊天室(socket.ioB/S)

尝试实现 socket.io 通信时收到 GET 400。 Node.js、ELB、Route 53、CloudFront 和 s3

Node.js + Socket.io 实现一对一即时聊天

CloudFlare 和 socket.io