---
title: "Go-學習筆記 vol.1"
url: https://geminixiang.com/posts/golang-learning-note-vol1/
description: "用 Go 寫一個簡易 WebSocket 聊天室：搭配 gin 與 melody 框架，並整理 struct 的定義與使用方式。"
published: 2022-09-04
category: "Programming"
tags: ["golang", "gin", "melody", "websocket"]
---

# Go-學習筆記 vol.1

# Golang 簡易聊天室

[geminixiang/simple_chat](https://github.com/geminixiang/simple_chat)

這周末學習了與MongoDB，使用了 mgo、mongo-go-driver 這兩個套件去學習，但...上手還需要一陣子，太久沒使用強型別，很多地方都還需要適應。

所以，這次先帶來 [Go into Web!-iThome](https://ithelp.ithome.com.tw/articles/10239615) 上所分享的小專案來進行學習，也能更快去熟悉語法及debug、build、log等開發技巧，話不多說，讓我們開始吧。

## 知識點們

### melody

> https://github.com/olahol/melody
> Minimalist websocket framework for Go

是一個2018年已經棄坑(喂~)的 websocket framework，是 based on gorilla/websocket 上封裝的一個 package，更容易使用，以外如果要找還有在維護、Star還夠多的messaging server 可以參考 [centrifugal/centrifugo](https://github.com/centrifugal/centrifugo)

回到正題，而因為它是 websocket 框架，網站的靜態文件還是得找個人來幫忙掛載，在 melody 的官方教學文件上，就是與 [gin](https://github.com/gin-gonic/gin) 一起配合，就讓我們來看看以下的 code~

```go
package main

import (
	"github.com/gin-gonic/gin"
	"gopkg.in/olahol/melody.v1"
	"net/http"
)

func main() {
  // 實例 gin、melody
	r := gin.Default()
	m := melody.New()

  // 把index.html掛載到 /
	r.GET("/", func(c *gin.Context) {
		http.ServeFile(c.Writer, c.Request, "index.html")
	})

  // melody's websocket 則是掛載到 /ws
	r.GET("/ws", func(c *gin.Context) {
    // gin的 response 與 request 轉手交給 melody 去 handle
		m.HandleRequest(c.Writer, c.Request)
	})

  // 那麼 melody 透過 handlemessage，當 message 進來時該如何處理，這邊的寫法是，有訊息進來將會告知所有 sessions
	m.HandleMessage(func(s *melody.Session, msg []byte) {
		m.Broadcast(msg)
	})

  // melody handleconnect 使用者連線，這邊我們定義websocket連線網址長得像
  // ws://localhost:5000/ws?id=Guest755
  m.HandleConnect(func(session *melody.Session) {
    // 取得url上的param id
    // := 冒號賦值，不用預先定義直接賦值
		id := session.Request.URL.Query().Get("id")
    // 廣播新的Message，這邊有個 GetByteMessage 會做 JSON encoding
		m.Broadcast(NewMessage("other", id, "加入聊天室").GetByteMessage())
	})

  // melody handleconnect 使用者離開後，傳訊息通知其他使用者
	m.HandleClose(func(session *melody.Session, i int, s string) error {
		id := session.Request.URL.Query().Get("id")
		m.Broadcast(NewMessage("other", id, "離開聊天室").GetByteMessage())
		return nil
	})

  // gin server run on port 5000
	r.Run(":5000")
}
```


### Struct 結構資料

非常像C++的struct，我目前使用起來可以說是一模一樣，可以定義一結構化的資料，使用已經定義好的Struct方式如下:
`Message{Event: "ABC", Name: "ABC", Content: "ABC", TimeStamp: time.Now()}`

看起來有點繁瑣吧，這邊提供一個func NewMessage，將一些param mapping到定義好的struct，可以更方便的使用。
```go
type Message struct {
	Event   string `json:"event"`
	Name    string `json:"name"`
	Content string `json:"content"`
	TimeStamp    time.Time `json:"timestamp"`
}

func NewMessage(event, name, content string) *Message {
	return &Message{
		Event:   event,
		Name:    name,
		Content: content,
		TimeStamp: time.Now(),
	}
}

func (m *Message) GetByteMessage() []byte {
	result, _ := json.Marshal(m)
	return result
}

---

## About the author

**Ying Xiang Zhao** (geminixiang) — DevOps Engineer, Taipei, Taiwan.

Ying Xiang Zhao（geminixiang）是住在台北的 DevOps 工程師，工作橫跨雲原生基礎設施、CI/CD、ML 模型部署與全端開發。這個部落格記錄 infra、資安與 AI coding agent 的實戰筆記；作品包含開源專案 mikan（把 AI coding agent 帶進 Slack / Telegram / Discord）與 tiny-agent（用四種語言實作的極簡 coding agent），瀏覽器內的影片編輯器 Studio，並經營旅遊分帳工具 SentriPay。

**Open to work** — DevOps Engineer / Platform Engineer / Site Reliability Engineer / AI Infrastructure Engineer · Taipei, Taiwan / Remote. Résumé: https://geminixiang.com/about/ (JSON: https://geminixiang.com/resume.json)

Topics: DevOps, Cloud Native, Kubernetes, Docker, Terraform, Google Cloud, CI/CD, Security, AI coding agents, ML model deployment, TypeScript, Python

Projects:
- [mikan](https://github.com/geminixiang/mikan) — Self-hosted AI coding agent for Slack, Telegram, Discord and GitHub with per-conversation sandboxes
- [tiny-agent](https://github.com/geminixiang/tiny-agent) — Minimal AI coding agents in TypeScript, Go, Python and Rust, plus a book on how they work
- [SentriPay](https://sentripay.com) — Travel expense splitter with multi-currency conversion and shareable, live-synced trip ledgers
- [Studio](https://studio.geminixiang.com) — Browser-based video editor built on WebCodecs

[About](https://geminixiang.com/about/) · [Résumé](https://geminixiang.com/about/) · [LinkedIn](https://linkedin.com/in/geminixiang/) · [GitHub](https://github.com/geminixiang) · [Twitter](https://x.com/geminixiang)
