Swift iOS 应用程序不使用 Socket.IO 连接到服务器
Posted
技术标签:
【中文标题】Swift iOS 应用程序不使用 Socket.IO 连接到服务器【英文标题】:Swift iOS application does not connect to Server using Socket.IO 【发布时间】:2017-01-05 13:37:13 【问题描述】:我即将编写一个非常简单的 ios 应用程序。我希望应用程序使用 Socket.IO 连接到服务器。我已经为我的项目安装了带有 Cocoapods 的 Socket.IO,一切都很顺利。 问题是在我运行服务器和应用程序模拟器之后,应用程序没有连接到服务器。我没有收到任何类型的错误消息或类似的东西,但是当连接套接字时,服务器应该在控制台/终端上打印一条消息。
这是套接字管理器类
import UIKit
import SocketIO
class SocketManager: NSObject
static let sharedInstance = SocketManager()
override init()
super.init()
var socket: SocketIOClient = SocketIOClient(socketURL: NSURL(string: "localhost:3000")!)
func establishConnection()
socket.connect()
func closeConnection()
socket.disconnect()
这是 AppDelegeate 类:
import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate
var window: UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool
// Override point for customization after application launch.
return true
func applicationWillResignActive(application: UIApplication)
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
func applicationDidEnterBackground(application: UIApplication)
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
SocketManager.sharedInstance.closeConnection()
func applicationWillEnterForeground(application: UIApplication)
// Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
func applicationDidBecomeActive(application: UIApplication)
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
SocketManager.sharedInstance.establishConnection()
func applicationWillTerminate(application: UIApplication)
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
最后是我用 node.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>Server Chat</h1>');
);
http.listen(3000, function()
console.log('Listening on *:3000');
);
io.on('connection', function(clientSocket)
console.log('a user connected');
);
【问题讨论】:
你确定你应该连接到localhost:6979
吗?不应该是localhost:3000
吗?
嗨,这是一个错误,我尝试了另一台服务器,所以 SocketManager 类的端口仍然是旧的。我的 SocketManager 类中的端口应该是 3000,我会更新它。但这并不能解决我的问题:/
有人得到解决方案吗?
【参考方案1】:
我会尝试使用 实际 IP 而不是“Localhost”,我认为它正在连接到它自己作为一个设备,这就是为什么没有出错
如果您尝试使用模拟器或实际设备,也许您应该提及 还要检查防火墙
【讨论】:
嗨,我用模拟器运行它,所以没有设备连接到我的 mac。我检查了我的防火墙,它实际上已停用。我还按照你说的写了我当前的 IP 地址,但都没有用。 当您运行服务器时,您是否收到“Listening on *:3000” 天哪,你救了我的命!这是解决方案!谢谢! 解决方案是什么@KárpátiAndrás 解决办法是什么?【参考方案2】:试着写 SocketIOClient(socketURL:URL(字符串:“http://192.168.0.8:3000”)!) 代替 SocketIOClient(socketURL:NSURL(字符串:“localhost:3000”)!) 并写“你的服务器IP地址”
我希望它对你有用
【讨论】:
【参考方案3】:这对我有用:
dict = [.connectParams(["payloadId": getPayloadId(), "version": getVersion()])]
socket = SocketIOClient(socketURL: URL(string: "http://localhost:8080")!, config: dict)
socket.connect()
socket.on("connect") data, ack in
if(self.socket.status == .connected)
print("socket connected")
else
self.reconnectSocket()
【讨论】:
什么是 getPayloadId() 和 getVersion()。请提供完整的示例,以便其他人能够正确理解。 基本上在 connectParams 中,您正在为您的服务器发送一个字典来唯一标识每个请求。这里 getPayloadId() 为您提供了一个唯一值(可以是 memberId 和当前时间戳的组合),您可以随每个请求发送该值。除此之外,您还可以发送其他值,包括 authToken、deviceType、appVersion、osVersion 等。【参考方案4】:// Case 1: This won't work
class Myclass
func initSocket()
let manager = SocketManager(socketURL: URL(string: BASE_URL)!, config: [.log(true), .compress])
socket = manager.defaultSocket
socket.on(clientEvent: .connect) data, ack in
print("SOCKET CONNECTED")
// Case 2: This works
class Myclass
let manager = SocketManager(socketURL: URL(string: BASE_URL)!, config: [.log(true), .compress])
var socket: SocketIOClient!
func initSocket()
socket = manager.defaultSocket
socket.on(clientEvent: .connect) data, ack in
print("SOCKET CONNECTED")
情况 1:服务器看到客户端已连接,但在 iOS 端,.connect
事件永远不会触发,一段时间后服务器上的 disconnect
事件会触发
【讨论】:
以上是关于Swift iOS 应用程序不使用 Socket.IO 连接到服务器的主要内容,如果未能解决你的问题,请参考以下文章
后端使用 Swift 和 Node.js 的 Socket.io 示例
应用程序进入后台时如何保持 Swift Socket IO 运行?