ios中SocketIO的实现

Posted

技术标签:

【中文标题】ios中SocketIO的实现【英文标题】:Implementation of SocketIO in ios 【发布时间】:2014-01-04 21:59:57 【问题描述】:

我想在我的项目中实现SocketIO。

我的项目的服务器端和客户端代码如下所示。

在客户端,有一个测试按钮,它向服务器端发送一个发布请求([self.afn post:@"/test" withParams:@ completion:^(id obj)])。 self.afn 是 AFNetworking library 的包装类的实例对象。

服务器端使用app.post('test', function()...函数捕获这个post请求 在这个发布请求处理程序中,我在newschannel 发出一个数据(hello: "world"),我希望在SocketIO library for Objective C 的didReceiveMessage 处理程序的客户端捕获这些数据。

我检查了,按钮成功发送了 post 请求,服务器端成功处理了这个 post 请求并在news 频道上发出了数据(hello:"world")。但是,客户端不会在 didReceiveMessage 处理程序上捕获此数据。

问题出在哪里?你有什么想法吗?

服务端和客户端的详细代码如下:

服务器端:

//server.js
var express = require('express');
var app = module.exports = express();
/* configure app ... */
var io = require('socket.io').listen(8090);
var mySocket;

io.sockets.on('connection', function (socket) 
    mySocket = socket;
); 

app.post("/test", function(req, res)
        if(mySocket)
            mySocket.emit('news',  hello: "world");
        
);

客户端:

//Client side in ObjectiveC
@implementation ViewController

- (void)viewDidLoad

    [super viewDidLoad];
    self.txtFrom.delegate = self;
    self.txtTo.delegate = self;

    //initialize socket
    self.socket = [[SocketIO alloc] initWithDelegate:self];
    [self.socket connectToHost: @"172.20.10.5" onPort:8090];



// IBAction for the test button to send a post request to the server to activate
- (IBAction)actTest:(id)sender 
    //self.afn is my wrapper class for AFNetworking
    [self.afn post:@"/test" withParams:@@"foo": @"bar" completion:^(id responseObj)
        NSLog(@"Response object: %@", responseObj);
    ];


- (void) socketIO:(SocketIO *)socket didReceiveMessage:(SocketIOPacket *)packet

    NSLog(@"didReceiveMessage() >>> data: %@", packet.data);

@end

编辑:

我听从了 Mathieu 'OtaK' Amiot 的建议,将[self.socket connectToHost: @"172.20.10.5" onPort:8090 withParams:nil withNamespace:@"news"];改为[self.socket connectToHost: @"172.20.10.5" onPort:8090];

现在,我可以在控制台看到消息,但是,当在客户端收到消息时,didReceiveMessagehandler 不会被调用。

当我从发件人发送消息时,事件的名称是“新闻”,但在客户端我没有提及事件名称。这可能是原因吗?

【问题讨论】:

我对@9​​87654337@ 没有很好的经验,但尝试将node.js 视为您的服务器端,我相信它会为您节省很多时间。 已经是nodejs了。 【参考方案1】:

编辑:最终答案是您应该使用 didReceiveEvent 委托方法而不是 didReceiveMessage

mySocket.emit('news', hello: "world"); 行中,您没有指定任何命名空间。 在您的 objc 代码中,您将套接字连接到命名空间:-)

您应该使用 then :io.of('/news').emit('news', hello: 'world' );

您将命名空间与事件名称混合在一起!

(或者只是在objc代码中将nil传递给命名空间,这样会更容易)

【讨论】:

感谢您的建议,我相应地编辑了我的帖子,但在客户端 didreceivemessage 仍然没有触发,我确信消息已到达客户端,因为我看到了控制台上的消息。当我从发件人发送消息时,事件的名称是"news",但在客户端我没有提及事件名称。会是这个原因吗? @ankakusu 也许你应该尝试使用这个委托而不是 didRecieveMessage :- (void) socketIO:(SocketIO *)socket didReceiveEvent:(SocketIOPacket *)packet; 是的,它捕获了didReceiveEvent。您能否编辑您的答案,然后我可以接受它作为答案:) 顺便问一下,didRecieveMessage 事件的功能是什么? Edited ;) 我想didRecieveMessage 是为原始 websocket 消息制作的,如下所述:github.com/LearnBoost/socket.io/wiki/Messaging【参考方案2】:

你可以试试这个方法

io.sockets.on('connection', function (socket) 

    app.post("/test", function(req, res)
        if(mySocket)
            socket.emit('news',  hello: "world");
        
    );

); 

而不是这个:

io.sockets.on('connection', function (socket) 
    mySocket = socket;
); 

app.post("/test", function(req, res)
        if(mySocket)
            mySocket.emit('news',  hello: "world");
        
);

【讨论】:

感谢您的建议,您的方式更安全,但在客户端 didreceivemessage 仍然不会触发,我确信消息已到达客户端,因为我看到了控制台上的消息。当我从发件人发送消息时,事件的名称是“新闻”,但在客户端我没有提到事件名称。会是这个原因吗? 我之前使用 SocketRocket(作为 socket.io 客户端)和 .net windows 服务开发了一个应用程序,但是我没有太多关于 node.js 的信息这个例子:tokbox.com/blog/… 可能对检查。

以上是关于ios中SocketIO的实现的主要内容,如果未能解决你的问题,请参考以下文章

ios如何在iOS中实现SocketIO

SocketIO介绍+SpringBoot整合SocketIO完成实时通信

netty-socketio堆外内存泄露排查盛宴

python-socketio 文档翻译

使用 gevent-socketio 和 Socket.IO.js 的 Python 瓶子微框架的最小示例

SocketIO4Net.Client 订阅频道