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 相关文章推荐
PNGHandler-借助JS让PNG图在IE下实现透明(包括背景图)
Aug 31 Javascript
js下通过prototype扩展实现indexOf的代码
Dec 08 Javascript
JavaScript的模块化:封装(闭包),继承(原型) 介绍
Jul 22 Javascript
node.js中的emitter.on方法使用说明
Dec 10 Javascript
javascript:void(0)是什么意思及href=#与href=javascriptvoid(0)的区别
Nov 13 Javascript
jQuery+CSS实现滑动的标签分栏切换效果
Dec 17 Javascript
jQuery+Ajax+PHP弹出层异步登录效果(附源码下载)
May 27 Javascript
微信小程序 侧滑删除(左滑删除)
May 23 Javascript
在vue项目中使用Nprogress.js进度条的方法
Jan 31 Javascript
Angular实现svg和png图片下载实现
May 05 Javascript
vue.js中ref及$refs的使用方法解析
Oct 08 Javascript
canvas 中如何实现物体的框选
Aug 05 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
用Simple Excel导出xls实现方法
2012/12/06 PHP
使用PHP导出Word文档的原理和实例
2013/10/21 PHP
PHP中UNIX时间戳和日期间的转换与计算实例
2014/11/19 PHP
关于URL最大长度限制的相关资料查证
2014/12/23 PHP
详解PHP的Yii框架的运行机制及其路由功能
2016/03/17 PHP
利用php输出不同的心形图案
2016/04/22 PHP
JQuery团队打造的javascript单元测试工具QUnit介绍
2010/02/26 Javascript
基于Jquery的标签智能验证实现代码
2010/12/27 Javascript
JQuery中DOM加载与事件执行实例分析
2015/06/13 Javascript
浅谈js中的变量名和函数名重名
2017/02/13 Javascript
jacascript DOM节点——元素节点、属性节点、文本节点
2017/04/18 Javascript
Angularjs2不同组件间的通信实例代码
2017/05/06 Javascript
浅谈jquery中ajax跨域提交的时候会有2次请求的问题
2017/11/10 jQuery
简单了解Vue computed属性及watch区别
2020/07/10 Javascript
[01:04:22]2018DOTA2亚洲邀请赛 3.31 小组赛 B组 IG vs EG
2018/04/01 DOTA
python通过自定义isnumber函数判断字符串是否为数字的方法
2015/04/23 Python
讲解Python的Scrapy爬虫框架使用代理进行采集的方法
2016/02/18 Python
用Python进行简单图像识别(验证码)
2018/01/19 Python
老生常谈python中的重载
2018/11/11 Python
对python中list的拷贝与numpy的array的拷贝详解
2019/01/29 Python
Python操作SQLite数据库过程解析
2019/09/02 Python
Python列表嵌套常见坑点及解决方案
2020/09/30 Python
python drf各类组件的用法和作用
2021/01/12 Python
CSS3 简写animation
2012/05/10 HTML / CSS
PUMA澳大利亚官方网站:德国运动品牌
2018/10/19 全球购物
亚洲颇具影响力的男性在线购物零售商:His
2019/11/24 全球购物
上课睡觉检讨书
2014/01/28 职场文书
宾馆总经理岗位职责
2014/02/14 职场文书
《社戏》教学反思
2014/04/15 职场文书
中央空调节能方案
2014/06/15 职场文书
暑期政治学习心得体会
2014/09/02 职场文书
2015年中个人总结范文
2015/03/10 职场文书
情感电台广播稿
2015/08/18 职场文书
position:sticky 粘性定位的几种巧妙应用详解
2021/04/24 HTML / CSS
jQuery ajax - getScript() 方法和getJSON方法
2021/05/14 jQuery
python迷宫问题深度优先遍历实例
2021/06/20 Python