最近幫朋友幫忙寫一個可以Demo的Protottype,有三個角色 Server,Client,Observer 許多Client會送資料給Server,Server處理這些資料之後匯集給Observer 說來不難的東西,因為用了我不熟的技術,golang + javascript,浪費太多時間 果然隔行如隔山啊,寫寫在路上遇到的問題
SSL / TLS Transport 由於想要練習,所以直接用SSL來當作傳輸協定,跟TCP大同小異,不過困難的是Certificate的產生 Server端
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 cert, err := tls.LoadX509KeyPair("certs/server.pem" , "certs/server.key" ) if err != nil { log.Fatalf("server: loadkeys: %s" , err) } config := tls.Config{Certificates: []tls.Certificate{cert}} config.Rand = rand.Reader service := "0.0.0.0:8000" listener, err := tls.Listen("tcp" , service, &config) if err != nil { log.Fatalf("server: listen: %s" , err) } for { conn, err := listener.Accept() if err != nil { log.Printf("server: accept: %s" , err) break } defer conn.Close() log.Printf("server: accepted from %s" , conn.RemoteAddr()) tlscon, ok := conn.(*tls.Conn) if ok { log.Print("ok=true" ) state := tlscon.ConnectionState() for _, v := range state.PeerCertificates { log.Print(x509.MarshalPKIXPublicKey(v.PublicKey)) } go handleClient(conn) } else { log.Print("reject connection" ) } }
Client端
1 2 3 4 5 6 7 8 9 10 cert, err := tls.LoadX509KeyPair("certs/client.pem" , "certs/client.key" ) if err != nil { log.Fatalf("server: loadkeys: %s" , err) } config := tls.Config{Certificates: []tls.Certificate{cert}, InsecureSkipVerify: true } conn, err := tls.Dial("tcp" , "127.0.0.1:8000" , &config) if err != nil { log.Fatalf("client: dial: %s" , err) } clientFunc(conn)
至於Certificate是用Openssl產生的,於是產生第二個問題
Websocket 這個坑實在死的不明不白 Server端原先這樣寫
1 2 3 4 5 6 7 http.HandleFunc("/ws" , func (w http.ResponseWriter, r *http.Request) { log.Print("New websocket arrive" ) serveWs(hub, w, r) }) if err := http.ListenAndServeTLS("localhost:8888" , "certs/server.pem" , "certs/server.key" , nil ); err != nil { log.Fatal("ListenAndServe:" , err) }
而Observer端則是
1 ws = new WebSocket("wss://127.0.0.1:8888/ws" )
看起來沒什麼問題,不過不然,目前的websocket不能接受 Self hosted certificate,然後就怎麼連都連不上了 為了省事,直接用ws
和http
傳輸了
Aggregate Json 我想要做的功能是假設 Client A傳送
1 [{Name : 'aaa' , Age : 18 }, {Name : 'bbb' , Age : 81 }]
Client B傳送`
1 [{Name : 'ccc' , Age : 28 }, {Name : 'bbb' , Age : 82 }]
Oberver會看到
1 [{Name : 'aaa' , Age : 18 }, {Name : 'bbb' , Age : 81 }, {Name : 'ccc' , Age : 28 }, {Name : 'bbb' , Age : 82 }]
我不太熟悉golang對json的操作,於是寫了醜陋無比的程式碼
1 2 3 4 5 6 7 8 9 10 11 12 type keyvalue map [string ]string var keyvalueslice []keyvaluefor _, v := range Map { var m1 []keyvalue if err := json.Unmarshal([]byte (v), &m1); err != nil { log.Print(err) } for _, obj := range m1 { keyvalueslice = append (keyvalueslice, obj) } } b, _ := json.Marshal(keyvalueslice)
實在感到羞恥啊…
React / Webpack 雖然知道React跟Webpack,不過實際拿來用是另外一回事 React還好,因為我沒用到太深的東西,不過webpack.config.js很複雜 要找Websocket Bug的時候,SourceMap還生不出來,只好土法煉鋼
Conclusion 隔行如隔山,不跳脫舒適圈去搞些平時不會搞的東西,什麼時候死都不知道 不過這次經驗真是讓我充滿挫折 Orz