您的位置:首页 > 其它

如何在snap中利用socket.io及websocket来进行实时数据更新

2017-02-07 16:07 781 查看
Socket.io可以使得我们的服务器和客户端进行双向的实时的数据交流。它比HTTP来说更具有传输数据量少的优点。同样地,websocket也具有同样的优点。你可以轻松地把你的数据发送到服务器,并收到以事件为驱动的响应,而不用去查询。在今天的教程中,我们来讲一下如何利用socket.io和websocket来做一个双向的通讯。

1)创建一个socket.io的服务器

首先我们先看一下我完成的一个项目:

https://github.com/liu-xiao-guo/socketio

我们首先看一下我们的snapcraft.yaml文件:

snapcraft.yaml

name: socketio
version: "0.1"
summary: A simple shows how to make use of socket io
description: socket.io snap example

grade: stable
confinement: strict

apps:
socket:
command: bin/socketio
daemon: simple
plugs: [network-bind]

parts:
nod:
plugin: nodejs
source: .


这是一个nodejs的项目。我们使用了nodejs的plugin。我们的package.json文件如下:

package.json

{
"name": "socketio",
"version": "0.0.1",
"description": "Intended as a nodejs app in a snap",
"license": "GPL-3.0",
"author": "xiaoguo, liu",
"private": true,
"bin": "./app.js",
"dependencies": {
"express": "^4.10.2",
"nodejs-websocket": "^1.7.1",
"socket.io": "^1.3.7"
}
}


由于我们需要使用到webserver,所有我们安装了express架构包。另外,我们使用到socket.io及websocket,所有,我们把这些包都打入到我们的snap包中。

再来看看我们的应用app.js的设计:

app.js

#!/usr/bin/env node

var express = require('express');
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);

app.get('/', function(req, res){
res.sendFile(__dirname + '/www/index.html');
});

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

//Whenever someone connects this gets executed
io.on('connection', function(socket){
console.log('A user connected');

setInterval(function(){
var value = Math.floor((Math.random() * 1000) + 1);
io.emit('light-sensor-value', '' + value);
// console.log("value: " + value)

// This is another way to send data
socket.send(value);
}, 2000);

//Whenever someone disconnects this piece of code executed
socket.on('disconnect', function () {
console.log('A user disconnected');
});

});

http.listen(4000, function(){
console.log('listening on *:4000');
});

var ws = require("nodejs-websocket")

console.log("Going to create the server")

String.prototype.format = function() {
var formatted = this;
for (var i = 0; i < arguments.length; i++) {
var regexp = new RegExp('\\{'+i+'\\}', 'gi');
formatted = formatted.replace(regexp, arguments[i]);
}
return formatted;
};

// Scream server example: "hi" -> "HI!!!"
var server = ws.createServer(function (conn) {

console.log("New connection")
var connected = true;

conn.on("text", function (str) {
console.log("Received "+str)
conn.sendText(str.toUpperCase()+"!!!")
})

conn.on("close", function (code, reason) {
console.log("Connection closed")
connected = false
})

setInterval(function(){
var value = Math.floor((Math.random() * 1000) + 1);
var data = '{"data":"{0}"}'.format(value)
if (connected){
conn.send(data);
}
}, 2000);
}).listen(4001)


在代码的第一部分,我们创建了一个webserver,它使用的端口地址是4000。我们也同时启动了socket.io服务器,等待客户端的连接。一旦有一个连接的话,我们使用如下的代码每过一段时间来发送一些数据:

//Whenever someone connects this gets executed
io.on('connection', function(socket){
console.log('A user connected');

setInterval(function(){
var value = Math.floor((Math.random() * 1000) + 1);
io.emit('light-sensor-value', '' + value);
// console.log("value: " + value)

// This is another way to send data
socket.send(value);
}, 2000);

//Whenever someone disconnects this piece of code executed
socket.on('disconnect', function () {
console.log('A user disconnected');
});

});


虽然这些数据是一些随机的,但是我们主要用来展示它是如何工作的。在实际的应用中,这些数据可以是从一些传感器中得到的。在我们的客户端中,我们可以打开webserver运行的地址:



我们可以看到数据不断地进来,并在我们的客户端中显示出来。具体的设计请参考在www目录中的index.html文件。

2)创建一个websocket的服务器

在我们的app.js中,我们利用如下的代码来实现一个websocket的服务器。端口地址为4001。

app.js

var ws = require("nodejs-websocket")

console.log("Going to create the server")

String.prototype.format = function() {
var formatted = this;
for (var i = 0; i < arguments.length; i++) {
var regexp = new RegExp('\\{'+i+'\\}', 'gi');
formatted = formatted.replace(regexp, arguments[i]);
}
return formatted;
};

// Scream server example: "hi" -> "HI!!!"
var server = ws.createServer(function (conn) {

console.log("New connection")
var connected = true;

conn.on("text", function (str) {
console.log("Received "+str)
conn.sendText(str.toUpperCase()+"!!!")
})

conn.on("close", function (code, reason) {
console.log("Connection closed")
connected = false
})

setInterval(function(){
var value = Math.floor((Math.random() * 1000) + 1);
var data = '{"data":"{0}"}'.format(value)
if (connected){
conn.send(data);
}
}, 2000);
}).listen(4001)


同样地,一旦有个连接,我们每隔两秒钟发送一个数据到我们的客户端。为了说明问题方便,我们设计了一个QML的客户端。

Main.qml

import QtQuick 2.4
import Ubuntu.Components 1.3
import Ubuntu.Components.Pickers 1.3
import Qt.WebSockets 1.0
import QtQuick.Layouts 1.1

MainView {
// objectName for functional testing purposes (autopilot-qt5)
objectName: "mainView"

// Note! applicationName needs to match the "name" field of the click manifest
applicationName: "dialer.liu-xiao-guo"

width: units.gu(60)
height: units.gu(85)

function interpreteData(data) {
var json = JSON.parse(data)
console.log("Websocket data: " + data)

console.log("value: " + json.data)
mainHand.value = json.data
}

WebSocket {
id: socket
url: input.text
onTextMessageReceived: {
console.log("something is received!: " + message);
interpreteData(message)
}

onStatusChanged: {
if (socket.status == WebSocket.Error) {
console.log("Error: " + socket.errorString)
} else if (socket.status == WebSocket.Open) {
// socket.sendTextMessage("Hello World....")
} else if (socket.status == WebSocket.Closed) {
}
}
active: true
}

Page {
header: PageHeader {
id: pageHeader
title: i18n.tr("dialer")
}

Item {
anchors {
top: pageHeader.bottom
left: parent.left
right: parent.right
bottom: parent.bottom
}

Column {
anchors.fill: parent
spacing: units.gu(1)
anchors.topMargin: units.gu(2)

Dialer {
id: dialer
size: units.gu(30)
minimumValue: 0
maximumValue: 1000
anchors.horizontalCenter: parent.horizontalCenter

DialerHand {
id: mainHand
onValueChanged: console.log(value)
}
}

TextField {
id: input
width: parent.width
text: "ws://192.168.1.106:4001"
}

Label {
id: value
text: mainHand.value
}
}
}
}
}


运行我们的服务器及客户端:



我们可以看到我们数值在不断地变化。这个客户端的代码在:https://github.com/liu-xiao-guo/dialer

在这篇文章中,我们展示了如何利用socket.io及websocket来进行双向的实时的通讯。在很多的物联网的应用中,我们可以充分利用这些通讯协议来更好地设计我们的应用。

更多阅读:https://github.com/snapcore/snapcraft/tree/master/demos/webchat
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: