0.소스 올린 이유.
샘플이라고 올라와 있지만, 실제로는 접속 실패 오류가 떠서 한참 구글링 했습니다.
server1.go 실행하고 client1.go 로 동작 확인하고, 웹 동작은 크롬 브라우저에서 websocket_client1.html 동작 확인 했습니다.
아래는 WebSocket 동작 샘플 소스 이며,
아래 링크에 있는 샘플들을 참고 했습니다.
https://github.com/gorilla/websocket
https://github.com/gorilla/websocket/tree/main/examples/chat
https://stackoverflow.com/questions/4361173/http-headers-in-websockets-client-api
https://www.golinuxcloud.com/golang-websocket/
https://www.tutorialspoint.com/webrtc/webrtc_rtcpeerconnection_apis.htm
server1.go
package main
import (
"fmt"
"log"
"net/http"
"github.com/gorilla/websocket"
)
// var upgrader = websocket.Upgrader{}
var upgrader = websocket.Upgrader{
ReadBufferSize: 1024,
WriteBufferSize: 1024,
// 아래 CheckOrigin 항목이 없으면, 크롬에서 클라이언트 올렸을때 접속 안됨.
CheckOrigin: func(r *http.Request) bool {
return true
},
}
func main() {
http.HandleFunc("/echo", func(w http.ResponseWriter, r *http.Request) {
conn, err := upgrader.Upgrade(w, r, nil) // error ignored for sake of simplicity
if err != nil {
log.Println("upgrade:", err)
log.Println("w:", w)
log.Println("r:", r)
return
}
for {
// Read message from browser
msgType, msg, err := conn.ReadMessage()
if err != nil {
log.Println("read:", err)
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 {
log.Println("write:", err)
return
}
}
})
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "This is GolinuxCloud's websocket server")
})
sPort := ":9090"
log.Println("server port ", sPort)
http.ListenAndServe(sPort, nil)
}
websocket_client1.html
<!DOCTYPE html>
<html>
<head>
<title>ws</title>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
</head>
<body>
<!-- websockets.html -->
<input id="input" type="text" />
<button onclick="send()">Send</button>
<pre id="output"></pre>
</body>
<script>
var input = document.getElementById("input");
var output = document.getElementById("output");
var socket = new WebSocket("ws://localhost:9090/echo");
//var socket = new WebSocket("ws://10.120.10.102:9090/echo");
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 = "";
}
</script>
</html>
client1.go
// #go run client1.go localhost:9090 echo
package main
import (
"bufio"
"fmt"
"log"
"net/url"
"os"
"os/signal"
"time"
"github.com/gorilla/websocket"
)
var SERVER = ""
var PATH = ""
var TIMESWAIT = 0
var TIMESWAITMAX = 5
var in = bufio.NewReader(os.Stdin)
func getInput(input chan string) {
result, err := in.ReadString('\n')
if err != nil {
log.Println(err)
return
}
input <- result
}
func main() {
arguments := os.Args
if len(arguments) != 3 {
fmt.Println("Need SERVER + PATH!")
return
}
SERVER = arguments[1]
PATH = arguments[2]
fmt.Println("Connecting to:", SERVER, "at", PATH)
interrupt := make(chan os.Signal, 1)
signal.Notify(interrupt, os.Interrupt)
input := make(chan string, 1)
go getInput(input)
URL := url.URL{Scheme: "ws", Host: SERVER, Path: PATH}
c, _, err := websocket.DefaultDialer.Dial(URL.String(), nil)
if err != nil {
log.Println("Error:", err)
return
}
defer c.Close()
done := make(chan struct{})
go func() {
defer close(done)
for {
_, message, err := c.ReadMessage()
if err != nil {
log.Println("ReadMessage() error:", err)
return
}
log.Printf("Received: %s", message)
}
}()
for {
select {
case <-time.After(4 * time.Second):
log.Println("Please give me input!", TIMESWAIT)
TIMESWAIT++
if TIMESWAIT > TIMESWAITMAX {
//syscall.Kill(syscall.Getpid(), syscall.SIGINT)
}
case <-done:
return
case t := <-input:
err := c.WriteMessage(websocket.TextMessage, []byte(t))
if err != nil {
log.Println("Write error:", err)
return
}
TIMESWAIT = 0
go getInput(input)
case <-interrupt:
log.Println("Caught interrupt signal - quitting!")
err := c.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, ""))
if err != nil {
log.Println("Write close error:", err)
return
}
select {
case <-done:
case <-time.After(2 * time.Second):
}
return
}
}
}
댓글
댓글 쓰기