期末临近,由于课程设计需要做一个匿名投票,签到的功能,打算通过Nodejs&socket.io来简单地实现长连接。第一篇技术相关,有点小激动。。。
安装环境
- Nodejs的环境十分简单,从https://nodejs.org/en/下载pkg,然后一路next。搞定后打开Terminal,输入
node -v
,查看Nodejs版本。 - 安装模块,例如安装express模块,则在Terminal中输入
npm install express
(npm:node package manage),这是在当前路径下安装模块,如果要安装全局模块,则需要执行npm install -g express
,卸载模块则是npm uninstall express
。操作起来十分方便。通过npm list
可以查看当前所安装的模块。 - 既然是基于socket.io,那当然得安装socket.io模块。
npm install socket.io
。
socket.io简单介绍
在使用Node的http模块创建服务器同时还要Express应用,因为这个服务器对象需要同时充当Express服务和Socket.io服务。可以通过如下代码创建一个socket监听。1
2
3
4
5
6
7
8
9var http = require('http');
var express = require('express');
var socket = require('socket.io');
var app = express(); //express实例
var server = http.createServer(app);
server.listen(3700, function( ){
console.log('监听端口3700');
});
var io = socket.listen(server);
就这样就可以创建一个监听localhost:3700的应用了。
在后面接着输入这一部分代码,就可以接收到get请求了。
1 | app.get('/',function(req,res){ |
当然post也是可以的,app.post()
就可以了。
关于Nodejs和express的基本用法,大家都可以在搜索引擎中搜索到。
socket.io模块相关文档可以到socket.io上查看。
接下来讲讲签到的需求。场景:会议开始,用户扫码签到,每当一个用户签到完成,所有参加同一个会议的客户端UI当前在线人数进行更新。
然后分析下整个过程主要可以分成那几个部分:
- 扫码之前,用户发起请求,建立Websocket连接,利用socket.io的房间功能,将每一个会议设置为一个房间,相关的用户加入相关的房间。
- 用户扫码进行签到,发起一个post请求,服务端接收post请求后,对数据库(mysql)进行操作,然后返回结果,同时通过socket.io反推客户端当前在线人数。
- 客户端(iOS)对相关事件进行监听,事件触发时,刷新相关UI。
分析完成,那就先开始实现服务端吧。
- 首先像之前一个,通过express和socket.io创建一个服务监听相应端口,然后通过io监听connection事件。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23//会议相关socket服务
io.of('/meeting').on('connection',function(socket){
console.log('一个客户端已连接meeting');
socket.emit('message','成功连接');
//进入会议室
socket.on('comeInMeeting',function (obj){
socket.name = obj.userID; //socketName 设置为userID
var roomName = obj.meetingID;
socket.join(roomName);
console.log(obj.userID+'进入会议室'+obj.meetingID);
socket.emit("comeInMeeting",{code:200});
});
//离开会议室
socket.on('comeOutMeeting',function (obj){
socket.leave(obj.meetingID);
console.log(socket.name+'离开会议室内'+obj.meetingID);
});
socket.on('message', function(obj) {
console.log('用户发了一个消息'+obj);
});
});
以上用到了命名空间(of(‘/meeting’)
),相关知识,可以查看搜索引擎。通过socket.join()
可以加入一个房间。socket.leave()
离开一个房间。
- 接下来添加一个post请求处理函数。
1 | app.post('/conferenceRegister',function(req,res){ |
其中的数据库操作部分暂且忽略。io.of(‘/meeting’).sockets[0].to(roomName).emit(‘meetingRegisterNum’, {registerNum:result.data.OnlineCountNum});
此处也是由于添加了命名空间,所以有of(‘/meeting’)
。socket.io的广播方法有很多,socket.to只是其中一种,但是我尝试其他的方法和命名空间配合使用,都无法像客户端推送数据。望大神帮忙解决!!!
服务端解决了(虽然实际花了很多时间QAQ),然后就是客户端了。iOS的socket.io Client 是swift语言编写的,在https://github.com/socketio/socket.io-client-swiftclone下来,当然可以直接用CocoaPodspod ‘Socket.IO-Client-Swift’, ‘~> 4.1.2’
。通过#import “<#项目名#>-Swift.h”
导入项目。因为我用的是OC,所以需要在引用文件名后加上Swift,使用桥接文件,这个桥接文件默认编译器会自动生成。
接下来的工作就很简单了,跟服务端差不多的操作。进入页面,在ViewDidLoad的时候实例化socket.io。然后添加命名空间,最后进行连接。具体代码如下:
1 | #import "socketDemo-Swift.h" |
添加一个点击方法来触发服务端的comeInMeeting事件,然后再添加监听meetingRegisterNum事件,来刷新UI。
1 | - (void)clickButton:(id)sender { |
这样点击按钮之后就可以加入服务端对应的房间中,当同一房间中有人进行签到,则会收到最新的在线人数。
其中的post请求部分未涉及,由于是demo,所以我是通过火狐的poster来发起post请求的。
差不多就这些步骤,新手接触Nodejs,只是用到了冰山一角,希望有Node大神指导。
webStorm的配置
我尝试了下用WebStorm来写Nodejs程序,通过一些配置,可以实现所有引用框架的智能提醒。
首先点击WebStrom 的设置按钮,弹出设置页面。
选择右侧菜单的languages&frameWorks–>libraries,就会看到如下界面。
看到了很多选项,然后点击download按钮,可以看到如下图,上面可以选择下载很多配置文件(用来实现智能提醒的)。其中的TypeScript中的配置文件都是一些第三方的智能提醒,以上我们用到的express和socket.io都在这里面。
如果说我们再typeScript中选中文件点击Download and install ,那么你中招啦。等上半小时也不会下载完成。那么具体原因呢?传送门
咦才那么一点点?按照视频的操作,可以下拉那个“Official libraries”,切换到“TypeScript community stubs”,就会出现很多很多东东。然后你做了,然后即使等半小时,也是空空如也!!怒了,是被墙了吗??我抓了一下包,神奇的,如果是Official libraries,会去亚马逊云上取xml数据,但是这个TypeScript community stubs却不会触发网络活动,神奇了!!难道是我用的daoban的原因??不得而知。
知道原因了,那么我们直接去对应git clone相应配置文件就好啦。例如我们去git上将express的配置文件copy下来。然后放在一个安全的目录下,不要丢桌面,不小心删了就没啦。(我是放在了webstorm的包文件夹内,生死共存亡)。然后就是回到原来的界面咯。
- 如下图,回到刚才的界面,不选择download,选择add,然后自己取一个名字,添加刚才git上搞下来的.d.ts文件,然后点击ok—>apply,最后神奇的发现,真的能提醒我express相关方法啦!!!