首页 > 上网技巧 > 电脑小技巧 > iOS使用WebSocket 实现服务器和客户端通信

iOS使用WebSocket 实现服务器和客户端通信

时间:2018-05-02 09:47 作者:QQ地带 我要评论

WebSocket是一个协议基于tcp,它能实现浏览器(客户端)和服务器之间双工通信,允许服务器主动发送消息给客户端.websocket没有出来之前,双工通信是通过多个http链接来实现也就是轮循的方式,效率低下,开销很大.
webSocket优点
 
websocket2端建立链接只需要一次握手过程然后2端就能形成一条快速的通道.
header很小,大概只有2bytes
服务器不在是一个被动返回数据的端,而是能实时有新数据就可以主动发送给浏览器
可以做什么
 
个推,即时通信.服务器不在是被动角色可以数据更新是可以主动告知客户端
有哪些第三库
 
CocoaAsyncSocket:https://github.com/robbiehanson/CocoaAsyncSocket
Facebook出品的SocketRocket https://github.com/facebook/SocketRocket
socket.io https://github.com/socketio/socket.io-client-swift。
需求:使用webscoket实现ios端2个手机的实时通信
 
demo(分为服务器+移动端ios) 基于socket.io
服务器
 
socket.io服务器API
 
io.on('connection',function(socket));
监听客户端连接,回调函数会传递本次连接的socket
 
io.sockets.emit('String',data);
给所有客户端广播消息
 
io.sockets.socket(socketid).emit('String', data);
给指定的客户端发送消息
 
socket.on('String',function(data));
监听客户端发送的信息
 
socket.emit('String', data);
给该socket的客户端发送消息
 
广播消息
//给除了自己以外的客户端广播消息
socket.broadcast.emit("msg",{data:"hello,everyone"}); 
 
//给所有客户端广播消息
io.sockets.emit("msg",{data:"hello,all"});
 
分组
socket.on('group1', function (data) {
        socket.join('group1');
});
socket.on('group2',function(data){
        socket.join('group2');
 });
踢出分组
socket.leave(data.room);
 
socket.emit('group1'),就可以加入group1分组;
socket.emit('group2'),就可以加入group2分组;
 
服务器对分组中的用户发送信息
//不包括自己
socket.broadcast.to('group1').emit('event_name', data);
//包括自己
io.sockets.in('group1').emit('event_name', data);
 
获取连接的客户端socket 
io.sockets.clients().forEach(function (socket) {
    //.....
})
 
获取分组信息
//获取所有房间(分组)信息
io.sockets.manager.rooms
 
//来获取此socketid进入的房间信息
io.sockets.manager.roomClients[socket.id]
 
//获取particular room中的客户端,返回所有在此房间的socket实例
io.sockets.clients('particular room')
mac搭建node.js服务器
 
检查一下你的电脑是否安装了命令行 node -v 和 npm -v
如果没有安装去官网下载https://nodejs.org/en/download/
安装完成以后创建一个文件夹然后创建一个package.json文件
代码如下
{
 "name": "socket-chat-example",
 "version": "0.0.1",
 "description": "my first socket.io app",
 "dependencies": {}
}
然后cd到该文件夹下执行npm install,这一步完成以后文件夹中多一个名叫node_modules文件夹
然后创建一个index.js文件代码如下
var app = require('express')();
var http = require('http').Server(app);
var io   = require('socket.io')(http);
 
 
 
app.get('/',function(req,res){
    res.sendfile(__dirname + '/index.html');
});
http.listen(3000,function () {
    console.log('listien 3000');
});
 
var socketArray = new Array();
 
 
//监听客户端链接,回掉函数会传递本次链接的sokcert.id
io.on('connection', function(socket){
    var islogin = false;
    console.log('**********新加入了一个用户*********',socket.id);
    socket.on('login',function (userId) {
       if(islogin) return;
        socket.userId = userId;
        socketArray.push(socket);
       islogin = true;
 
    });
//本例子没用到这个坚挺
    socket.on('privateMessage',function (data) {
        console.log(data);
    })
//监听服务求发送chat message标识符的信息
    socket.on('chat message', function(data){
        var to   = data.toUser;
        var message = data.message;
        for(var i = 0;i<socketArray.length;i++){
            var receiveData = socketArray[i];
            if (receiveData.userId == to){
                console.log('*******socket Id =',receiveData.socketId);
//将消息分发给目标用户:怎么知道谁是目标用户呢,根据发送消息离的toUser和secket.userId:来找到该客户端的secketid发送信息
                io.to([receiveData.id]).emit('privateMessage',''+receiveData.userId+':'+message);
            }
        }
    });
    socket.on('disconnect',function () {
        console.log('***********用户退出登陆************,'+socket.id);
    })
});
此时 在终端输入
cd到web文件夹执行node index.js 打印 listien 3000那么服务器完成了
客户端
 
客户端api
客户端socket.on()监听的事件:
connect:连接成功
connecting:正在连接
disconnect:断开连接
connect_failed:连接失败
error:错误发生,并且无法被其他事件类型所处理
message:同服务器端message事件
anything:同服务器端anything事件
reconnect_failed:重连失败
reconnect:成功重连
reconnecting:正在重连
当第一次连接时,事件触发顺序为:connecting->connect;当失去连接时,事件触发顺序为:disconnect->reconnecting(可能进行多次)->connecting->reconnect->connect。
使用
 
使用cocoapods导入
Podfile中代码
use_frameworks!
platform :ios, '8.0'
target 'SocketIO_Test’ do #项目名
  pod 'Socket.IO-Client-Swift'
end
保存
 
pod install
 
代码
 
- (SocketIOClient *)client{
    if (!_client) {
        //服务器地址
        NSURL* url = [[NSURL alloc] initWithString:@"http://127.0.0.1:3000"];
         //初始化socketIo给定url 后面的config是对这个socket的一些配置,比如log设置为yes
        _client = [[SocketIOClient alloc] initWithSocketURL:url config:@{@"log": @YES, @"forcePolling": @YES}];
    }
    return _client;
}
 
- (void)connection{
    //正在链接
    [self.client on:@"connecting" callback:^(NSArray * data, SocketAckEmitter * ack) {
 
    }];
     //链接成功
    [self.client on:@"connect" callback:^(NSArray* data, SocketAckEmitter* ack) {
        NSLog(@"*************\n\niOS客户端上线\n\n************");
 
        //向服务器发送一个login标识符的信息 信息内容为30342,那么服务器就知道30342的客户端用户上线了
        [self.client emit:@"login" with:@[@"30342"]];
    }];
 
 
    //监听服务器发送来的消息 msg标识符类的消息(用处当运行代码时服务器知道你上线了法送一个hello world给你)
    [self.client on:@"msg" callback:^(NSArray * _Nonnull event, SocketAckEmitter * _Nonnull ack) {
        NSLog(@"我上线了服务器发给我的消息是%@",event[0]);
 
    }];
    //监听服务器发送来的消息 privateMessage
    [self.client on:@"privateMessage" callback:^(NSArray * _Nonnull event, SocketAckEmitter * _Nonnull ack) {
 
        if (event[0] && ![event[0] isEqualToString:@""]) {
 
            [self.messageArray insertObject:event[0] atIndex:0];
            [self.messageTableView insertRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:0 inSection:0]] withRowAnimation:UITableViewRowAnimationTop];
        }
    }];
    //客户端与服务器断开
    [self.client on:@"disconnect" callback:^(NSArray * _Nonnull event, SocketAckEmitter * _Nonnull ack) {
        NSLog(@"*************\n\niOS客户端下线\n\n*************%@",event?event[0]:@"");
    }];
    //错误发送,并且无法被其他事件类型所处理
    [self.client on:@"error" callback:^(NSArray * _Nonnull event, SocketAckEmitter * _Nonnull ack) {
        NSLog(@"*************\n\n%@\n\n*************",event?event[0]:@"");
    }];
 
    //reconnect_failed:重连失败
    //reconnect:成功重连
    //reconnectin:正在重连
    //当第一次链接时:事件触发顺序为connecting->connect;当失败连击时:disconnect->reconnecting(可能进行多次)->connecting->reconnect->connect。
    //连接
    [self.client connect];
 
 
    //断开链接
  //  [self.client disconnect];
 
}
//按钮点击事件
- (IBAction)sendMessage:(id)sender {
    if (self.inputView.text.length>0) {
        //发送消息 chat message是一个标识符,服务器正在监听 意思是发送chat message类型的消息给30621,消息为:self.inputView.text
//需要看效果的话用模拟器运行一下,然后在打开一个模拟器把这里和最上面的30342换一下.就能用2个模拟器互相发消息
        [self.client emit:@"chat message" with:@[@{@"toUser":@"30621",@"message":self.inputView.text}]];
        NSString *myUserstr = [NSString stringWithFormat:@"我:%@",self.inputView.text];
        [self.messageArray insertObject:myUserstr atIndex:0];
 
       // [self.messageTableView insertRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:0 inSection:0]] withRowAnimation:UITableViewRowAnimationTop];
        [self.messageTableView reloadData];
        self.inputView.text = @"";
    }
 
}
 

标签: iOS
顶一下
(0)
0%
踩一下
(0)
0%

Google提供的广告