Socket + ProtocolBuffer实现消息通讯(Swift)

最近在学习webRTC里面的Socket机制,回忆一下之前用到的Socket+ProtocolBuffer,这次用Swift实现简单的IM消息通讯。步骤如下:
  • 一 依赖库集成
    依赖库:
    SwiftSocket

    protobuf-swift
    根据自己的需要创建对应消息格式的的proto文件
    Socket + ProtocolBuffer实现消息通讯(Swift)_第1张图片

    然后执行命令 生成对应的 swift 文件

protoc person.proto --swift_out="./"

在这里插入图片描述

  • 二 服务器端
    1,启动监听,接收连接
class ServerManager: NSObject {
   fileprivate lazy var serverSocket = TCPServer(addr: "172.18.220.109", port: 7999)
   fileprivate var  isServerRunning : Bool = false
   fileprivate lazy var clientManagers : [ClientManager] = [ClientManager]()
}
extension ServerManager {
    
    func startRunning(){
        //1 开启监听
        if serverSocket.listen().0 {
            print("listen success!")
            isServerRunning = true
        }else{
            print("listen failed!")
            return
        }
        //2 开始接收连接
      
        DispatchQueue.global().async {
            while self.isServerRunning {
                if let client = self.serverSocket.accept(){
                    DispatchQueue.global().async {
                        print("accept connect")
                        self.handleClient(client)
                    }
                }
                
            }
        }
        
        
    }
    
    func stopRunning(){
        isServerRunning = false
    }
    
}

2,响应消息

  func startReadMsg(){
        //参数是消息的长度
        isClientConnected = true
        
        let timer = Timer(fireAt: Date(), interval: 1, target: self, selector: #selector(checkHeartBeat), userInfo: nil, repeats: true)
        RunLoop.current.add(timer, forMode:.commonModes)
        timer.fire()
        
        while isClientConnected {
            if let lMsg = tcpClient.read(4){
                // 1 读取数据长度
                let headData = Data(bytes: lMsg, count: 4)
                var length : Int = 0
                (headData as NSData).getBytes(&length, length: 4)
                
                // 2 读取类型
                guard let typeMsg = tcpClient.read(2) else {
                    print("read type failed!")
                    return;
                }
                let typeData = Data(bytes: typeMsg, count: 2)
                var type : Int = 0
                (typeData as NSData).getBytes(&type, length: 2)
                print(type)
                
                // 3 读取消息
                guard let msg = tcpClient.read(length) else {
                    print("read msg failed!")
                    return;
                }
                let msgData = Data(bytes: msg, count: length)
                
                //如果是离开房间消息 就从系统移除
                if type == 1{
                    tcpClient.close()
                    delegate?.removeClient(self)
                }else if type == 100{
                    heartTimeCount = 0
                    let msg = String(data: msgData, encoding: .utf8)
                    print(msg ?? "")
                    continue
                }
                
                //发送消息
                let totalData = headData + typeData + msgData
                delegate?.sendMsgToClient(totalData)
                

            }else{
                self.removeClient()
            }
        }
        
    }

3 心跳包处理

  @objc fileprivate func checkHeartBeat() {
        heartTimeCount += 1
        if heartTimeCount >= 10 {
            self.removeClient()
        }
    }
    
    
    private func removeClient(){
        delegate?.removeClient(self)
        isClientConnected = false
        print("客户端断开了连接")
        tcpClient.close()
    }
    
  • 三 客户端

1,连接服务器,发送心跳

    fileprivate lazy var socket : ZBSocket  = ZBSocket(addr: "172.18.220.163", port: 7999)

    fileprivate var timer : Timer!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        if socket.connectServer() {
            print("connectServer")
            socket.startReadMsg()
            
            //发送心跳
            timer = Timer(fireAt: Date(), interval: 9, target: self, selector: #selector(sendHeartBeat), userInfo: nil, repeats: true)
            RunLoop.main.add(timer, forMode: .commonModes)
            
            
            
        }else {
            print("connectServer failed!")
        }
       

2,发送消息

@IBAction func btnClick(_ sender: UIButton) {
        switch sender.tag {
        case 0:
            socket.sendJoinRoom()
        case 1:
            socket.sendLeaveRoom()
        case 2:
            socket.sendTextMsg("你好啊, 张大鱼")
        case 3:
            socket.sendGiftMsg("大火箭", "http://www.baidu.com", 1000)
        default:
            print("未识别消息")
        }
    }
    
  • 四 Demo
    Demo

你可能感兴趣的:(IOS)