目录结构
├── Dockerfile
├── README.md
├── docker-compose.yaml
├── go.mod
├── go.sum
├── index.html
├── main.go
├── nginx.conf
Docker-compose 文件
version: '3'
services:
nginx:
image: nginx
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
ports:
- 9980:80
privileged: true
test:
build:
context: .
ports:
- 9981:8088
- 加载本地 nginx 配置
- 9980 -> 转发到nginx80 -> 代理到后端 go 的 8088 ws端口
- 9981-> go的后端服务
nginx 配置
#user nobody;
worker_processes 2;
#工作模式及连接数上线
events {
worker_connections 1024; #设置最大连接数
}
http {
include mime.types;
default_type application/octet-stream;
#sendfile 指令指定 nginx 是否调用 sendfile 函数(zero copy 方式)来输出文件,对于普通应用,
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
# 开启GZIP
gzip on;
#必须添加的
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
upstream websocket {
#转发到服务器上相应的ws端口
server test:8088;
}
# # 监听 80 端口,转发请求到 3000 端口
server {
#监听端口
listen 80;
#编码格式
charset utf-8;
location /ws {
#转发到http://websocket
proxy_pass http://websocket;
proxy_read_timeout 300s;
proxy_send_timeout 300s;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
#升级http1.1到 websocket协议
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
}
}
- 使用test域访问后端go服务
- 转发到
http://websocket
到upstream websocket
服务端
package main
import (
"fmt"
"net/http"
"github.com/gorilla/websocket"
)
var upgrader = websocket.Upgrader{
ReadBufferSize: 1024,
WriteBufferSize: 1024,
}
func main() {
http.HandleFunc("/echo", func(w http.ResponseWriter, r *http.Request) {
conn, _ := upgrader.Upgrade(w, r, nil) // error ignored for sake of simplicity
for {
// Read message from browser
msgType, msg, err := conn.ReadMessage()
if err != nil {
return
}
// Print the message to the console
fmt.Printf("%s sent: %s\n", conn.RemoteAddr(), string(msg))
// Write message back to browser
if err = conn.WriteMessage(msgType, msg); err != nil {
return
}
}
})
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
http.ServeFile(w, r, "index.html")
})
http.ListenAndServe(":8088", nil)
}
html 文件
<meta charset="utf-8"/>
<input id="input" type="text" />
<button onclick="send()">Send</button>
<pre id="output"></pre>
<script>
var input = document.getElementById("input");
var output = document.getElementById("output");
var socket = new WebSocket("ws://localhost:9981/echo");
socket.onopen = function () {
output.innerHTML += "Status: Connected\n";
};
socket.onmessage = function (e) {
output.innerHTML += "Server: " + e.data+1 + "\n";
};
function send() {
socket.send(input.value);
input.value = "";
}
</script>