Socket.io适用于Swift4 iOS

5

我遇到了麻烦,不知道如何将websocket功能实现到我的swift代码中。

我已经完成了服务器实现和另一个JavaScript客户端。它们运作良好。因此,我相信websocket服务器没有问题。

但是如果我在Swift中编写代码,它不起作用。控制台上没有错误消息或任何信息显示。

以下是我的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 = ""
            }
        }
    }
}

我希望在我的控制台上看到“socket connected”消息,但当应用程序运行时,我认为套接字出了问题。但是没有找到任何错误消息,因此我不知道出了什么问题。我怀疑是否需要在我的info.plist中进行一些设置,但是我不知道如何编写。请给我一些建议?

这是答案 https://dev59.com/e6rka4cB1Zd3GeqPkN35 只是在你的情况下不要传递令牌 - Wings
控制台上没有任何输出。没有任何消息被显示。 - Kazzz Studio
你能否审核一下我的代码,@KazzzStudio?你只需要在全局范围内设置你的管理对象。 - Harshal Valanda
是的,我做到了。当我尝试连接到我的WebSocket服务器时,我可以收到消息。 - Kazzz Studio
请注意,socket.io和WebSockets不同(尽管socket.io可能在内部使用WebSockets)。 - Myst
1个回答

4

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: 管理器正在被释放

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

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

  1. 检查服务器和客户端端的socket.io版本是否一致,不一致可能会导致此错误
  2. 在info.plist中添加“ App Transport Security Settings”键(字典类型)和子键“ Allow Arbitrary Loads”(布尔类型),值为YES。

谢谢你的建议。我尝试了你的代码,但是出现了以下错误信息:["Got unknown error from server Welcome to socket.io."]。这是一个套接字错误。因为另一个客户端(JavaScript)可以连接成功,所以我不知道出了什么问题。 - Kazzz Studio

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接