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('\r\n')
     tempkey = arr[2].split(': ')[1]
     print('key =', tempkey)
     accpet = ws_accept_key(tempkey).decode('utf-8')
     print('accpet = ', accpet)
     yy = 'GET HTTP/1.1\r\nConnection: Upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Accept: '
     yy = yy + accpet + '\r\n\r\n'        
     # conn.send(yy.encode('utf-8'))
     conn.sendall(bytes(yy.encode('utf-8')))


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM