500px技术周报002
socket.io
基于websocket实现客户端和服务器实时通讯,服务器采用的是node.js ,客户端支持java、c++、swift。
服务器搭建
第一步检查当前环境是否安装了node.js
node -v
npm -v
如果没有, 下载mac版node.js并安装。
然后新建一个文件夹,在里面执行vim package.json
输入一下内容
{
"name": "realtime-server",
"version": "0.0.1",
"description": "my first realtime server",
"dependencies": {}
}
然后执行
npm install --save express
npm install --save socket.io
然后执行vim index.js
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
app.get('/', function(req, res){
res.send('<h1>Welcome Realtime Server</h1>');
});
//在线用户
var onlineUsers = {};
//当前在线人数
var onlineCount = 0;
io.on('connection', function(socket){
console.log('a user connected');
//监听新用户加入
socket.on('login', function(obj){
//将新加入用户的唯一标识当作socket的名称,后面退出的时候会用到
socket.name = obj.userid;
//检查在线列表,如果不在里面就加入
if(!onlineUsers.hasOwnProperty(obj.userid)) {
onlineUsers[obj.userid] = obj.username;
//在线人数+1
onlineCount++;
}
//向所有客户端广播用户加入
io.emit('login', {onlineUsers:onlineUsers, onlineCount:onlineCount, user:obj});
console.log(obj.username+'加入了聊天室');
});
//监听用户退出
socket.on('disconnect', function(){
//将退出的用户从在线列表中删除
if(onlineUsers.hasOwnProperty(socket.name)) {
//退出用户的信息
var obj = {userid:socket.name, username:onlineUsers[socket.name]};
//删除
delete onlineUsers[socket.name];
//在线人数-1
onlineCount--;
//向所有客户端广播用户退出
io.emit('logout', {onlineUsers:onlineUsers, onlineCount:onlineCount, user:obj});
console.log(obj.username+'退出了聊天室');
}
});
//监听用户发布聊天内容
socket.on('message', function(obj){
//向所有客户端广播发布的消息
io.emit('message', obj);
console.log(obj.username+'说:'+obj.content);
});
});
http.listen(3000, function(){
console.log('listening on *:3000');
});
启动服务器 执行
node index.js
停止服务器使用control+C
客户端
CocoaPods方式集成
由于v10.0.0版本更新,doubleEncodeUTF8 已经被弃用,如果服务器使用的是老版本,客户端使用最新的代码,则会出现中文乱码情况。建议使用之前的版本,下面的例子中通过commit号来指定使用哪个版本。
Podfile里的内容如下:
platform :ios, '9.0'
use_frameworks!
target 'test' do
pod 'Socket.IO-Client-Swift' ,:git => 'https://github.com/socketio/socket.io-client-swift.git',:commit => '1949b1fd487abb4301f57c608645357b8195aa2e'
end
客户端代码如下
@import SocketIO;
NSString* socketUrlString = @"http://localhost:3000"";
NSDictionary* config = @{@"log":@NO,@"forcePolling":@YES,@"reconnects":@YES};
self.socketIOClient = [[SocketIOClient alloc] initWithSocketURL:[NSURL URLWithString:socketUrlString] config:config];
[self.socketIOClient on:@"connect" callback:^(NSArray * data, SocketAckEmitter * ack) {
NSLog(@"socketIOClientConnect");
NSLog(@"data = %@",data);
[self.socketIOClient emit:@"message" with:@[@"心跳包"]];
}];
[self.socketIOClient on:@"disconnect" callback:^(NSArray * data, SocketAckEmitter * ack) {
NSLog(@"socketIOClientDisconnect");
NSLog(@"data = %@",data);
}];
[self.socketIOClient on:@"error" callback:^(NSArray * data, SocketAckEmitter * ack) {
NSLog(@"socketIOClientError");
NSLog(@"data = %@",data);
}];
[_socketIOClient on:@"reconnect" callback:^(NSArray * data, SocketAckEmitter * ack) {
NSLog(@"socketIOClientReconnect");
NSLog(@"data = %@",data);
}];
[self.socketIOClient on:@"message" callback:^(NSArray * data, SocketAckEmitter * ack) {
NSLog(@"socketIOClientMessage");
NSLog(@"data = %@",data);
NSString *string =data[0];
NSLog(@"Received \"%@\"", string);
}];
[_socketIOClient connect];
好了可以测试了,注意因为设置的是localhost所以请用模拟器测试,否则需要执行ip。测试内容有2:
1、连上服务器以后,停掉服务器,客户端是否能检测到
2、客户端断网以后能否重练,是否有次数限制,时间限制
3、心跳包的处理
framework方式打包使用
由于swift语法还在不断更新,如果更新后需要更新代码进行编译,但是如果更新了代码则有可能就不能使用了,如果避免在swift语法更新后不重新编译也能使用?使用framework方式集成,因为已经将代码编译成了二进制文件,以后就更swift无关了。
下载 socket.io-client-swift代码,然后git checkout 1949b1fd487abb4301f57c608645357b8195aa2e
分别在模拟器和 Generic iOS Device下build,然后再合成
lipo -create **/**/*.framework/* **/**/*.framework/* -output 输出地址/*
查看合成后情况
lipo -info /Users/zhangruquan/Downloads/trySwift/Debug-iphoneos/SocketIO.framework/SocketIO
然后将Modules/SocketIO.swiftmodule里面的内容拷贝到一起。x86_64.swiftdoc、x86_64.swiftmodule、arm.swiftdoc、arm.swiftmodule、arm64.swiftdoc、arm64.swiftmodule
将加工后的framework拷贝到要使用的地方,项目上右键-》Targets-》General-》embedded Binaries-》+ 选中你的framework,如果是swift写的还要-》Build Settings-》Always Embed Swift Standard Libraries ,选择YES。
代码形式使用
拷贝代码到项目目录下,添加到项目里。设置-》Build Settings-》Packaging-》Defines Module -》Yes
新建头文件*-Bridging-Header.h,将其绝对路径复制到:设置-》Build Settings-》Swift compiler general-》Objective-C bridging Header。
在要使用的地方执行 #import “*-Swift.h”