Socket server với Golang và socket.io - Ứng dụng chat realtime đơn giản


  • Trùm cuối

    maxresdefault (2).jpg

    Ứng dụng thực tiễn

    Áp dụng vào trong một bối cảnh cụ thể và chúng ta có thể thấy được websockets quan trọng như thế nào. Tưởng tượng rằng chúng ta có một ứng dụng chat có thể lấy về tất cả các tin nhắn gần nhất từ máy chủ duy nhất và đẩy lên tất cả các itn nhắn mới lên cùng một máy chủ.

    Sử dụng REST API?

    Để có thể làm được real-time chat, bạn phải gửi yêu cầu liên tục đến server API để lấy về những tin nhắn mới nhất.

    Điều này dẫn đến việc có khoảng 60 yêu cầu gửi lên mỗi phút cho một client. Nếu chúng ta có thể xây dựng thành công một dịch vụ và càng ngày chúng ta sẽ có nhiều traffic hơn và "khủng bố" ứng dụng của chúng ta, máy chủ của chúng ta sẽ bắt đầu bị quá tải bởi hàng triệu request API mỗi phút.

    Ví dụ về Socket

    Nếu chúng ta cân nhắc về viễn cảnh sử dụng websockets thay thế cho REST API:

    • Mỗi client sẽ duy trì chỉ duy nhất một kết nối đến máy chủ.
    • Với 1000 client chúng ta chỉ cần duy trì 1000 kết nối socket.
    • Nếu một người gửi một tin nhắn, sau đó máy chủ sẽ đẩy tin nhắn và cập nhật đến 1000 client khác.
    • Với phương thức này chúng ta làm giảm tối đa network traffic đến server. Chúng ta sẽ tiết kiệm được kinh phí cho số lượng ứng dụng server và chúng ta cần chạy và chúng ta có thể xử lý hàng ngàn clients mà không cần tốn quá nhiều công sức và chi phí.

    Triển khai Golang Server

    Để triển khai một websocket với Go, chungs ta có khá nhiều sự lựa chọn. Trong bài viết này mình sẽ sử dụng giải pháp phổ biến nhất đó là socket.io

    Cài đặt go-socket.io

    Chúng ta có thể cài đặt package sử dụng go get như bên dưới:

    go get github.com/googollee/go-socket.io
    

    Và sau đó chúng ta include nó vào chương trình Go như sau:

    import "github.com/googollee/go-socket.io"
    

    Server đơn giản

    Chúng ta hãy xem ví dụ mẫu dưới đây:

    package main
    
    import (
    	"log"
    	"net/http"
    
    	socketio "github.com/googollee/go-socket.io"
    )
    
    func main() {
    
    	server, err := socketio.NewServer(nil)
    	if err != nil {
    		log.Fatal(err)
    	}
    
    	server.On("connection", func(so socketio.Socket) {
    
    		log.Println("on connection")
    
    		so.Join("chat")
    
    		so.On("chat message", func(msg string) {
    			log.Println("emit:", so.Emit("chat message", msg))
    			so.BroadcastTo("chat", "chat message", msg)
    		})
    
    		so.On("disconnection", func() {
    			log.Println("on disconnect")
    		})
    	})
    
    	server.On("error", func(so socketio.Socket, err error) {
    		log.Println("error:", err)
    	})
    
    	http.Handle("/socket.io/", server)
    
    	fs := http.FileServer(http.Dir("static"))
    	http.Handle("/", fs)
    
    	log.Println("Serving at localhost:5000...")
    	log.Fatal(http.ListenAndServe(":5000", nil))
    }
    

    Hãy cùng phân tích mã nguồn trên nào

    Ở mã nguồn mẫu trên chúng ta sẽ làm mọi thứ trong hàm main(). Đầu tiên chúng ta định nghĩa một socket.io server mới bằng cách gọi socketio.NewServẻ(nil) trước khi định nghĩa các phương thức hoạt động và xử lý lỗi.

    Bên trong hàm server.On('connection',...) chúng ta sẽ log ra những kết nối thành công trước sau đó join phòng chat sử dụng so.Join("chat").

    Sau đó chúng ta sẽ chỉ định điều gì sẽ xảy ra khi chúng ta nhận được một tin nhắn mới từ một socket đã kết nối. Mỗi khi server của chúng ta nhận được event này chúng ta gọi so.BroadcastTo("chat", "tin nhắn", msg) sẽ gửi message đến tất car các socket đang kết nối ở thời điểm hiện tại. Điều này có nghĩa là một client có thể thấy được tất cả các tin nhắn gửi đến từ các client khác.

    Cuối cùng chúng ta định nghĩa cho event "disconnection", trong ví dụ hày chúng ta chỉ đơn giản log ra client đã ngắt kết nối.

    Giao diện kết nối cho ứng dụng

    Okay, chúng ta cần một giao diện đơn giản để test xem ứng dụng có hoạt động như mong muốn không.

    Hãy tạo một file index.html bên trong thư mục dự án.

    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <meta http-equiv="X-UA-Compatible" content="ie=edge" />
        <title>Go WebSocket Tutorial</title>
      </head>
      <body>
        <h2>Hello World</h2>
    
        <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.1.1/socket.io.js"></script>
        <script>
          const socket = io("http://localhost:5000/socket.io/");
        </script>
      </body>
    </html>
    

    Sau đó chạy websocket server bằng cách gọi:

    $ go run main.go
    
    2019/03/12 07:54:06 Serving at localhost:5000...
    2019/03/12 07:54:15 on connection
    2019/03/12 07:54:16 on connection
    

    Server đang chạy ở cổng 5000 với URL http://localhost:5000. Bạn có thể mở URL này trên trình duyệt và xem những kết nối mới trong output log của server.

    Bây giờ, bạn đã xây dựng một giao diện kết nối trực tiếp đến Go websocket server thành công rùi đấy 😁

    Mì ăn liền

    https://github.com/TutorialEdge/Go/tree/master/go-websocket-tutorial



Có thể bạn cũng quan tâm

.
DMCA.com Protection Status