• iOS webSocket整理


    iOS处方接入Socket调研。

    项目背景:

    纳里医生使用Object-C开发,为了避免引入swift产生混编,影响编译速度。故Socket的方案从OC框架中进行选择。

    框架选择:

    为了实时获取服务器的最新信息,长连接的经历了,轮询 -》长轮询 -》websocket 三个阶段。

    轮询 长轮询 websocket
    定时发送请求 实时更新 实时更新
    消耗大,延迟 客户端发送请求,服务器用更新是响应 使用HTTP进行握手,TCP/UDP进行数据传输,

    OC websocket 方案选择

    基于使用Github星数,初步选择 CocoaAsyncSocket 和 SocketRocket

    实现原理:
    基于Socket API(为了便于使用对TCP/UDP进行了封装)

     //1.生成内核socket;2。与文件描述符绑定
     socket(AF_UNIX, SOCK_STREAM, 0);
     //建立连接,包含三次握手
     connect(sockfd, (struct sockaddr *)&address, len);
     //绑定一个IP地址和端口到socket套接字上
     bind(server_sockfd, (struct sockaddr *)&server_address, server_len);
     //半连接队列、全连接队列 
     int listen(int sockfd, int backlog)
     //返回一个new的socket文件描述符(不占用端口号)
     accept(server_sockfd,(struct sockaddr *)&client_address, client_len);
     //断开连接,包含四次挥手(TCP将尝试发送已排队等待发送到对端的任何数据,发送完毕后发生的是正常的TCP连接终止序列。TIME_WAIT原因)
     int close(int sockfd); 
    
    由于OC对Socket有更深层次的封装,故 CocoaAsyncSocket 和 SocketRocket 使用的是 NSOutputSteam 和 NSInputStream 进行的数据的读取操作。同时由于NSStream不能读取远程数据,故使用的是对应的CFStream(CFReadStreamRef/CFWriteStreamRef)来实现。
    

    CocoaAsyncSocket 和 SocketRocket 使用对比

    CocoaAsyncSocket SocketRocket
    线程管理 已封装CGD线程安全 已封装CGD线程安全
    连接方式 多种方式 URL形式
    必须根目录
    单独的心跳消息
    自动接收服务器消息
    故综合分析,为了使用方便,选择SocketRocket作为长连接的方案。

    服务端简单的python代码

    import hashlib
    import base64
    import socket
    
    def ws_accept_key(ws_key):
     """calc the Sec-WebSocket-Accept key by Sec-WebSocket-key
     come from client, the return value used for handshak
    
     :ws_key: Sec-WebSocket-Key come from client
     :returns: Sec-WebSocket-Accept
    
     """
     try:
     	magic = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
     	sha1 = hashlib.sha1()
     	sha1.update((ws_key + magic).encode('utf-8'))        
     	return base64.b64encode(sha1.digest())
     except Exception as e:
     	print("出错了", e)
     	return None
    
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    
    server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    # 绑定IP,端口
    server_socket.bind(("0.0.0.0", 80))
    # 监听
    server_socket.listen(5)
    print ("show key = ", ws_accept_key('pHuz2gMvj8tYkR4E+Q4gOA=='))
    while 1:
     conn, addr = server_socket.accept()
     print('地址', addr)
     while 1:
         receiveMsg = conn.recv(1024)
         print('接收到 ', receiveMsg.decode('utf-8'))
         tempRequest = receiveMsg.decode('utf-8')
         if tempRequest == "":
         	continue
         arr = tempRequest.split('
    ')
         tempkey = arr[2].split(': ')[1]
         print('key =', tempkey)
         accpet = ws_accept_key(tempkey).decode('utf-8')
         print('accpet = ', accpet)
         yy = 'GET HTTP/1.1
    Connection: Upgrade
    Upgrade: websocket
    Sec-WebSocket-Accept: '
         yy = yy + accpet + '
    
    '        
         # conn.send(yy.encode('utf-8'))
         conn.sendall(bytes(yy.encode('utf-8')))
    
  • 相关阅读:
    用VisualC#.NET编写服务器日期控件
    全局程序集缓存GAC是什么概念
    HttpRequest.Filter 属性
    创建ASP.Net自定义控件
    js/javascript 判断变量未定义
    DevExpress 汉化(简单、实用、快速)
    一个页面标题和过滤输出的解决方案
    用VisualC#.NET编写服务器日期控件(源碼)
    ASP.NET多语言支持组件简介
    ASP.NET服务器控件编程浅析
  • 原文地址:https://www.cnblogs.com/jisa/p/13596688.html
Copyright © 2020-2023  润新知