1. 什么是socket?
在计算机通信领域,socket 被翻译为“套接字”,它是计算机之间进行通信的一种约定或一种方式。通过 socket 这种约定,一台计算机可以接收其他计算机的数据,也可以向其他计算机发送数据。
2. 什么是websocket?
WebSocket是一种网络通信协议,是HTML5新增的特性,实现了基于浏览器的远程socket,使浏览器和服务器可以进行全双工通信。
3. 要实现什么样的效果?
-
socket服务端和web服务端实现数据双向通信。socket服务端可以是任何语言实现(c++、java、php、go等),任何部署方式(本机、远程)
-
web服务端(go 实现)和前端通过websocket实现数据双向通信.
-
socket服务、web服务、前端实现数据双向通信。
前端通过websocket发送数据给web服务 -》 web服务 -》 web服务将数据通过socket推送给远程服务端
远程服务通过socket将数据推送给web服务 -》 web服务 -》 web服务将数据通过websocket推送给前端
远程服务和前端即使数据发送者也是接收者。
web服务是数据中转战。(也可以处理业务需求)
4. 如何实现?
在实现三方通信数据双向通信之前,先实现
- 远程服务与web服务之间通过socket进行全双工通信
- web服务通过websocket将数据主动推送给前端并接收前端发来的数据
1. 远程服务与web服务之间通过socket进行全双工通信
socket服务可用其他任何语言实现(c++、java、php等)。这里采用go
server: 远程服务
- 监听
listener, err := net.Listen("tcp", "127.0.0.1:5412")
- 建立连接
conn, err := listener.Accept()
- 读 (注意: 如果数据太长,需要分片处理)
reader := bufio.NewReader(os.Stdin)
fmt.Print("请输入服务端发送的数据:")
sendinfo, err := reader.ReadString('\n')
if err != nil {fmt.Println("读取服务端要发送的数据出错!")continue
}
- 写入
sendinfo = strings.TrimSpace(sendinfo)
if sendinfo == "exit" {fmt.Println("退出服务端")return
}
conn.Write([]byte(sendinfo))
client: web服务
- 连接
conn, err := net.Dial("tcp", "127.0.0.1:5412")
- 读
for {n, err := conn.Read(buffer[:])if err != nil {fmt.Println("客户端读取socket服务端数据出错")break}fmt.Println("客户端读取socket数据是:", string(buffer[:n]))
}
- 写入
fmt.Print("请输入要发送给socket服务端的数据: ")
msg, err := reader.ReadString('\n')
if err != nil {fmt.Println("读取客户端要发送的数据出错!")return
}
msg = strings.TrimSpace(msg)
if msg == "exit" {fmt.Println("退出socket客户端")return
}
conn.Write([]byte(msg))
2. web服务基于websocket和前端通信
web服务
- 升级HTTP
ar upgrader = websocket.Upgrader{ReadBufferSize: 1024,WriteBufferSize: 1024,CheckOrigin: func(r *http.Request) bool {return true},
}ws, err = upgrader.Upgrade(w, r, nil)
- 读
func read() {for {_, p, err := ws.ReadMessage()if err != nil {log.Println(err)return}log.Println("Received message:", string(p))}
}
- 写
func write() {reader := bufio.NewReader(os.Stdin)for {fmt.Println("请输入要发送给socket服务端的数据: ")msg, err := reader.ReadString('\n')err = ws.WriteMessage(websocket.TextMessage, []byte(msg))if err != nil {log.Println(err)return}}
}
前端
var input = document.getElementById("input");
var output = document.getElementById("output");
var socket = new WebSocket("ws://localhost:1234");socket.onopen = function () {output.innerHTML += "Status: Connected\n";
};socket.onmessage = function (e) {output.innerHTML += "Server: " + e.data + "\n";
};function send() {socket.send(input.value);input.value = "";
}
3. 三方双向通信
实现了第一步和第二步就可以实现第三步,将第一步和第二步的代码进行合并即可。
唯一不同这里定义里两个无缓冲的通道.
-
前端将数据发送给web服务,web服务拿到数据写入chanMess中。在web服务和远程服务通信期间,就可以读chanMess中的数据,然后将数据推送给远程服务
-
远程服务将数据推送给web服务,web服务拿到数据写入socketMess中。在web服务和前端通信期间,就可以读socketMess中的数据,然后将数据推送给前端
var chanMess = make(chan []byte) // 存储 websocket数据
var socketMess = make(chan []byte) // 存储 socket数据