iOS + node.js使用Socket.IO框架进行实时通信示例


Posted in Javascript onApril 14, 2017

Socket.IO是一个基于WebSocket的实时通信库,在主流平台都有很好的支持,此文主要是通过一个小例子来演示Socket.IO的使用。

基础环境搭建

新建一个文件夹(JS工程),创建一个package.json,复制以下内容并保存。

{
 "name": "socket-chat-example",
 "version": "0.0.1",
 "description": "my first socket.io app",
 "dependencies": {}
}

然后执行npm命令,安装我们需要的依赖(Express和Socket.IO), 请确保你电脑已经有node环境

在项目根目录也就是package.json所在的目录在终端执行以下命令

npm install --save express@4.10.2

npm install --save socket.io

进度条读完后会多这么一个文件夹,此时Express和Socket.IO就已经安装好了,这和iOS的Cocopods差不多,以模块化进行加载。

iOS + node.js使用Socket.IO框架进行实时通信示例

然后新建一个index.js作为服务端,再建一个index.html作为客户端。(为了方便演示,我这里有两个客户端,一个是iOS端,一个是浏览器端)

index.html

这也是官方Demo的演示界面,UI上没做修改

iOS + node.js使用Socket.IO框架进行实时通信示例

代码如下

<!doctype html>
<html>
 <head>
  <title>Socket.IO chat</title>
  <style>
   * { margin: 0; padding: 0; box-sizing: border-box; }
   body { font: 13px Helvetica, Arial; }
   form { background: #000; padding: 3px; position: fixed; bottom: 0; width: 100%; }
   form input { border: 0; padding: 10px; width: 90%; margin-right: .5%; }
   form button { width: 9%; background: rgb(130, 224, 255); border: none; padding: 10px; }
   #messages { list-style-type: none; margin: 0; padding: 0; }
   #messages li { padding: 5px 10px; }
   #messages li:nth-child(odd) { background: #eee; }
  </style>
 </head>
 <body>
  <ul id="messages"></ul>
  <form action="">
   <input id="m" autocomplete="off" /><button>Send</button>
  </form>
 </body>
</html>

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');
});

开启了一个Server,监听3000端口,然后回到项目根目录,在终端输入node index.js

如果出现listen 3000则表明服务开启成功了,此时在浏览器访问http://localhost:3000 就能看到index.html页面了

iOS客户端的集成

新建一个iOS工程,在终端cd到项目根目录创建一个Podfile文件

vim Podfile

复制以下内容

use_frameworks!

target 'SocketIO_Chat_Example' do #项目名
  pod 'Socket.IO-Client-Swift', '~> 8.2.0'
end

保存退出,执行命令安装依赖

pod install or pod install --verbose --no-repo-update

请确保已经有cocopods环境

iOS端的UI

iOS + node.js使用Socket.IO框架进行实时通信示例

使用Socket.IO

此时我们的客户端和服务端都已经有了Socket.IO的环境了,接下来就是使用它进行聊天了。

Socket.IO中事件的处理主要通过这两个方法来实现的

on(_ event: String, callback: NormalCallback)

emit(_ event: String, _ items: AnyObject...)

on方法为接收事件的方法,emit为发送事件的方法

我们的需求是让浏览器和iOS客户端进行单聊

服务端的处理

要想发送到指定的客户端,需要知道当前客户端的id(Socket.IO的id,例:3t60BArlK47a2fA-AAAd),但是客户端并不清楚,客户端只知道我们自己定义的id,所以我们要将Socket.IO的Id和我们自己定义的id绑定并存储起来。

var socketArray = new Array();

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);
  })
  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){
        io.to([receiveData.socketId]).emit('privateMessage',''+receiveData.userId+':'+message);
      }
    }
  });
  socket.on('disconnect',function () {
    console.log('***********用户退出登陆************,'+socket.id);
  })
});

客户端的处理

浏览器的处理

<script src="/socket.io/socket.io.js"></script>
<script src="http://code.jquery.com/jquery-1.11.1.js"></script>
<script>
  var socket = io();
  socket.emit('login','30621');
  $('form').submit(function(){
    socket.emit('chat message',{'toUser':'30342','message':$('#m').val()} );
    $('#m').val('');
    return false;
  });
  socket.on('chat message', function(msg){
    $('#messages').append($('<li>').text(msg));
  });
  socket.on('privateMessage',function (msg) {
    $('#messages').append($('<li>').text(msg));
  });
</script>

iOS端的处理

iOS在初始化的时候需要一个config字典,config可以配置诸如log日志输出等设置

- (SocketIOClient *)client{
  if (!_client) {
    NSURL* url = [[NSURL alloc] initWithString:@"http://localhost:3000"];
    _client = [[SocketIOClient alloc] initWithSocketURL:url config:@{@"log": @YES, @"forcePolling": @YES}];

  }
  return _client;
}

- (void)connection{

  [self.client on:@"connect" callback:^(NSArray* data, SocketAckEmitter* ack) {
    NSLog(@"*************\n\niOS客户端上线\n\n*************");
    [self.client emit:@"login" with:@[@"30342"]];
  }];
  [self.client on:@"chat message" 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:@"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]:@"");
  }];
  [self.client connect];

}
//按钮点击事件
- (IBAction)sendMessage:(id)sender {
  if (self.inputView.text.length>0) {

    [self.client emit:@"chat message" with:@[@{@"toUser":@"30621",@"message":self.inputView.text}]];
    [self.messageArray insertObject:self.inputView.text atIndex:0];
    [self.messageTableView insertRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:0 inSection:0]] withRowAnimation:UITableViewRowAnimationTop];
    self.inputView.text = @"";
  }

}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
getElementByIdx_x js自定义getElementById函数
Jan 24 Javascript
Javascript实现简单二级下拉菜单实例
Jun 15 Javascript
利用jquery操作Radio方法小结
Oct 20 Javascript
JavaScript拖拽、碰撞、重力及弹性运动实例分析
Jan 08 Javascript
JavaScript 数组some()和filter()的用法及区别
May 20 Javascript
使用Script元素发送JSONP请求的方法
Jun 12 Javascript
JS实现改变HTML上文字颜色和内容的方法
Dec 30 Javascript
three.js实现围绕某物体旋转
Jan 25 Javascript
jQuery EasyUI之验证框validatebox实例详解
Apr 10 jQuery
Node爬取大批量文件的方法示例
Jun 28 Javascript
Vue触发隐藏input file的方法实例详解
Aug 14 Javascript
js实现上传图片并显示图片名称
Dec 18 Javascript
JavaScript Canvas绘制圆形时钟效果
Aug 20 #Javascript
基于JavaScript实现的插入排序算法分析
Apr 14 #Javascript
基于JavaScript实现的折半查找算法示例
Apr 14 #Javascript
AngularJS之自定义服务详解(factory、service、provider)
Apr 14 #Javascript
基于JavaScript实现的顺序查找算法示例
Apr 14 #Javascript
vue组件中点击按钮后修改输入框的状态实例代码
Apr 14 #Javascript
angularjs实现首页轮播图效果
Apr 14 #Javascript
You might like
php权重计算方法代码分享
2014/01/09 PHP
PHP编程入门的基本语法知识点总结
2016/01/26 PHP
PHP7生产环境队列Beanstalkd用法详解
2020/05/19 PHP
Jquery替换已存在于element上的event的方法
2010/03/09 Javascript
jQuery的实现原理的模拟代码 -1 核心部分
2010/08/01 Javascript
JS获取DropDownList的value值与text值的示例代码
2014/01/07 Javascript
javascript实现将文件保存到本地方法汇总
2015/07/26 Javascript
跟我学习javascript的执行上下文
2015/11/18 Javascript
javascript实现获取浏览器版本、浏览器类型
2015/12/02 Javascript
前端jquery部分很精彩
2016/05/03 Javascript
12个非常实用的JavaScript小技巧【推荐】
2016/05/18 Javascript
浅谈对Angular中的生命周期钩子的理解
2017/07/31 Javascript
Vue-Router实现组件间跳转的三种方法
2017/11/07 Javascript
Angular ui-roter 和AngularJS 通过 ocLazyLoad 实现动态(懒)加载模块和依赖
2018/11/25 Javascript
图解NodeJS实现登录注册功能
2019/09/16 NodeJs
微信小程序实现canvas分享朋友圈海报
2020/06/21 Javascript
从零开始用webpack构建一个vue3.0项目工程的实现
2020/09/24 Javascript
解决element-ui的下拉框有值却无法选中的情况
2020/11/07 Javascript
python结合selenium获取XX省交通违章数据的实现思路及代码
2016/06/26 Python
python分布式环境下的限流器的示例
2017/10/26 Python
django模板语法学习之include示例详解
2017/12/17 Python
python 实现selenium断言和验证的方法
2019/02/13 Python
python实现异常信息堆栈输出到日志文件
2019/12/26 Python
基于keras输出中间层结果的2种实现方式
2020/01/24 Python
Python开发之身份证验证库id_validator验证身份证号合法性及根据身份证号返回住址年龄等信息
2020/03/20 Python
Anthropologie英国:美国家喻户晓的休闲服装和家居产品品牌
2018/12/05 全球购物
英国办公家具网站:Furniture At Work
2019/10/07 全球购物
加拿大领先家居家具网上购物:Aosom.ca
2020/05/27 全球购物
财务经理岗位职责
2013/11/09 职场文书
业务主管岗位职责
2013/11/20 职场文书
宿舍违规用电检讨书
2014/02/16 职场文书
函授毕业生自我鉴定范文
2014/03/25 职场文书
欢迎领导标语
2014/06/27 职场文书
七年级英语教学反思
2016/02/15 职场文书
公司会议开幕词
2016/03/03 职场文书
使用javascript解析二维码的三种方式
2021/11/11 Javascript