用于 swift4 ios 的 Socket.io

Posted

技术标签:

【中文标题】用于 swift4 ios 的 Socket.io【英文标题】:Socket.io for swift4 ios 【发布时间】:2018-10-08 06:52:31 【问题描述】:

我遇到了如何在我的 swift 代码中实现 websocket 功能的麻烦。

我已经完成了一个服务器实现和另一个 javascript 客户端。 他们运作良好。 所以,我相信websocket server没有错。

但如果我用 swift 编写代码,它就不起作用。不会发生错误,控制台上也不会显示任何消息。

这是我的快速代码。

import UIKit
import SocketIO

class ChatViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UITextFieldDelegate 


    @IBOutlet weak var tableView: UITableView!

    var bottomView: ChatRoomInputView!

    var chats: [ChatEntity] = []

    var socket: SocketIOClient!

    override func viewDidLoad() 
        super.viewDidLoad()

        tableView.delegate = self
        tableView.dataSource = self

        // Initialize WebSocket
        let manager = SocketManager(socketURL: URL(string: "http://example.com:8081")!, config: [.log(true), .compress])
        socket = manager.defaultSocket

        socket.on(clientEvent: .connect) data, ack in
            print("socket connected")
        

        socket.on("server_to_client") [weak self] data, ack in
            print ("get Massage!!!")
        

        socket.connect()

        socket.emit("join_room", with: [getRegistrationId()])
        socket.emit("client_to_server", with: ["ack_client"])

        setupUI()
    


    override func didReceiveMemoryWarning() 
        super.didReceiveMemoryWarning()
    

    override func viewWillDisappear(_ animated: Bool) 
        super.viewWillDisappear(animated)
    

    override func viewWillAppear(_ animated: Bool) 
        super.viewWillAppear(animated)
    

    override var canBecomeFirstResponder: Bool 
        return true
    

    override var inputAccessoryView: UIView? 
        return bottomView
    

    func setupUI() 
        self.view.backgroundColor = UIColor(red: 113/255, green: 148/255, blue: 194/255, alpha: 1)
        tableView.backgroundColor = UIColor(red: 113/255, green: 148/255, blue: 194/255, alpha: 1)

        tableView.separatorColor = UIColor.clear
        tableView.estimatedRowHeight = 10000
        tableView.rowHeight = UITableViewAutomaticDimension
        tableView.allowsSelection = false
        tableView.keyboardDismissMode = .interactive

        tableView.register(UINib(nibName: "YourChatViewCell", bundle: nil), forCellReuseIdentifier: "YourChat")
        tableView.register(UINib(nibName: "MyChatViewCell", bundle: nil), forCellReuseIdentifier: "MyChat")

        self.bottomView = ChatRoomInputView(frame: CGRect(x: 0, y: 0, width: self.view.frame.width, height: 60))
        bottomView.chatTextField.delegate = self
        bottomView.textSendButton.addTarget(self, action: #selector(self.chatTextSendButton(_:)), for: .touchUpInside)

    

    func numberOfSections(in tableView: UITableView) -> Int 
        return 1
    

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
        return self.chats.count
    

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
        let chat = self.chats[indexPath.row]
        if chat.isMyChat() 
            let cell = tableView.dequeueReusableCell(withIdentifier: "MyChat") as! MyChatViewCell
            cell.clipsToBounds = true
            // Todo: isRead
            cell.updateCell(text: chat.text, time: chat.time, isRead: true)
            return cell
         else 
            let cell = tableView.dequeueReusableCell(withIdentifier: "YourChat") as! YourChatViewCell
            cell.clipsToBounds = true
            cell.updateCell(text: chat.text, time: chat.time, pic: RemoshinData.getDoctorPic())
            return cell
        
    

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) 
        print(indexPath)
    

    func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat 
        return 10
    


    func textFieldShouldReturn(_ textField: UITextField) -> Bool 
        textField.resignFirstResponder()
        return true
    

    func textFieldShouldClear(_ textField: UITextField) -> Bool 
        return true
    

    func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool 
        textField.inputFieldBorderBottom(color: Utils.getColor(),
                                     x: textField.center.x,
                                     y: textField.center.y,
                                     w: textField.frame.size.width,
                                     h: textField.frame.size.height)
        bottomView.chatTextField = textField
        return true
    
    func textFieldShouldEndEditing(_ textField: UITextField) -> Bool 
        textField.inputFieldBorderBottom(color: UIColor.lightGray,
                                     x: textField.center.x,
                                     y: textField.center.y,
                                     w: textField.frame.size.width,
                                     h: textField.frame.size.height)
        return true
    


    @objc func chatTextSendButton(_ sender: AnyObject) 
        let chatText = bottomView.chatTextField.text!

        if (chatText != "") 
            let _mainViewController = MainViewController()
            let jsonData = _mainViewController.sendChatText(_registration_id: getRegistrationId(), _chat_text: chatText)

            if(jsonData["status"].string! == "success") 
                socket.emit("client_to_server", with: ["update_chat"])

                let chat = ChatEntity(text: jsonData["chat_text"].string!, time: "", userType: .I)
                chats.append(chat)
                tableView.reloadData()

                bottomView.chatTextField.text = ""
            
        
    

我想在应用程序运行时在控制台上看到“套接字已连接”消息。我认为套接字有问题。但我不知道出了什么问题,因为没有找到错误消息。我怀疑我是否需要在我的 info.plist 中进行一些设置。但是,我不知道怎么写。

请给我一些建议?

【问题讨论】:

这里是答案***.com/questions/50001818/… 只是不要在你的情况下传递令牌 控制台没有线路。不显示任何消息。 你在查看我的代码@KazzzStudio 吗?你只需要在全局范围内设置你的经理对象 是的,我做到了。当我尝试连接到我的 websocket 服务器时,我可以收到消息.. 请注意socket.io与WebSockets不同(虽然socket.io内部可能使用WebSockets)。 【参考方案1】:

socket.io-client-swift

var manager:SocketManager!

var socketIOClient: SocketIOClient!

override func viewDidLoad() 
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
    ConnectToSocket()


func ConnectToSocket() 

    manager = SocketManager(socketURL: URL(string: "your url")!, config: [.log(true), .compress])
    socketIOClient = manager.defaultSocket

    socketIOClient.on(clientEvent: .connect) data, ack in
        print(data)
        print("socket connected")
    

    socketIOClient.on(clientEvent: .error)  (data, eck) in
        print(data)
        print("socket error")
    

    socketIOClient.on(clientEvent: .disconnect)  (data, eck) in
        print(data)
        print("socket disconnect")
    

    socketIOClient.on(clientEvent: SocketClientEvent.reconnect)  (data, eck) in
        print(data)
        print("socket reconnect")
    

    socketIOClient.connect()

更新

在您的情况下:SocketManager:Manager 正在被释放

通过管理器创建的套接字由管理器保留。因此,至少,必须维护一个对管理器的强引用以保持套接字处于活动状态。

["从服务器收到未知错误欢迎使用 socket.io。"]

    检查服务器端和客户端的socket.io版本,两者不匹配可能导致此错误 在 info.plist(字典类型)和子键“允许任意加载”(布尔类型)中添加一个“应用程序传输安全设置”键,值为 YES。

【讨论】:

感谢您的建议。我尝试了您的代码,并收到以下错误消息。 [“从服务器收到未知错误欢迎使用 socket.io。”] 套接字错误。我不知道出了什么问题,因为另一个客户端(javascript)连接正确。

以上是关于用于 swift4 ios 的 Socket.io的主要内容,如果未能解决你的问题,请参考以下文章

socket.io 不适用于传输:['xhr-polling']

Socket.io + NodeJS 不适用于 Heroku

CORS 不适用于 hapijs 和 socket.io

Socket.io 不适用于 nginx

Connect-redis 商店不适用于 socket.io

socket.io 连接不适用于 react.js