0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

GoでWebSocketを使用した通知システムを作成する:[Redis連携]

Last updated at Posted at 2025-03-10

はじめに

前回の記事では、GoでWebSocketを使った基本的なリアルタイム通信を実装しました。
今回は、さらに応用的なWebSocketの活用方法として、通知システムの作成およびRedisを使ったスケーラブルなWebSocketサーバーの構築を解説します。

対象読者

  • WebSocketを活用して通知システムを実装したい方
  • Redisを使ってWebSocketサーバーをスケールアウトしたい方
  • 複数のWebSocketクライアントを効率的に管理したい方

目次

  1. WebSocketを活用した通知システムの作り方
    • 通知システムの仕組み
    • WebSocketサーバーの実装
    • クライアント側の実装(JavaScript)
  2. Redisを使ったWebSocketサーバーの構築方法
    • Redis Pub/Subの仕組み
    • GoでのRedis連携(go-redis
    • マルチインスタンス対応のWebSocketサーバー

1. WebSocketを活用した通知システムの作り方

1.1 通知システムの仕組み

WebSocketを活用すると、サーバーからリアルタイムでクライアントに通知を送信できます。

例:通知システムの流れ

  1. クライアントがWebSocketに接続する
  2. サーバーが特定のイベント(新しい投稿、メッセージなど)を検知
  3. サーバーが該当ユーザーにリアルタイム通知を送信

1.2 WebSocketサーバーの実装

まず、GoでWebSocketの通知サーバーを実装します。

server.go

package main

import (
    "fmt"
    "net/http"
    "sync"
    "github.com/gorilla/websocket"
)

type Client struct {
    conn *websocket.Conn
}

var upgrader = websocket.Upgrader{
    CheckOrigin: func(r *http.Request) bool { return true },
}
var clients = make(map[*Client]bool)
var mu sync.Mutex

func handleWebSocket(w http.ResponseWriter, r *http.Request) {
    conn, err := upgrader.Upgrade(w, r, nil)
    if err != nil {
        fmt.Println("WebSocket connection failed:", err)
        return
    }
    client := &Client{conn: conn}
    mu.Lock()
    clients[client] = true
    mu.Unlock()

    defer func() {
        mu.Lock()
        delete(clients, client)
        mu.Unlock()
        conn.Close()
    }()

    for {
        _, _, err := conn.ReadMessage()
        if err != nil {
            break
        }
    }
}

func sendNotification(message string) {
    mu.Lock()
    defer mu.Unlock()
    for client := range clients {
        client.conn.WriteMessage(websocket.TextMessage, []byte(message))
    }
}

func main() {
    http.HandleFunc("/ws", handleWebSocket)
    fmt.Println("WebSocket server running on ws://localhost:8080/ws")
    http.ListenAndServe(":8080", nil)
}
  • clientsマップでWebSocketに接続しているクライアントを管理
  • sendNotification()で接続中のすべてのクライアントにメッセージを送信

1.3 クライアント側の実装(JavaScript)

index.html

<script>
    const ws = new WebSocket("ws://localhost:8080/ws");

    ws.onmessage = function(event) {
        alert("通知: " + event.data);
    };
</script>
  • WebSocketからのメッセージを受け取るとポップアップ通知を表示

2. Redisを使ったWebSocketサーバーの構築方法

2.1 Redis Pub/Subの仕組み

Redis Pub/Sub(パブリッシュ・サブスクライブ)を使うと、異なるWebSocketサーバー間で通知を共有できます。

2.2 GoでのRedis連携(go-redis

Redisをインストール

docker run --name redis -d -p 6379:6379 redis

Goライブラリをインストール

go get github.com/go-redis/redis/v8

server_redis.go

package main

import (
    "context"
    "fmt"
    "github.com/go-redis/redis/v8"
    "net/http"
    "github.com/gorilla/websocket"
)

var ctx = context.Background()
var rdb = redis.NewClient(&redis.Options{
    Addr: "localhost:6379",
})

func handleWebSocket(w http.ResponseWriter, r *http.Request) {
    conn, _ := upgrader.Upgrade(w, r, nil)
    defer conn.Close()
    sub := rdb.Subscribe(ctx, "notifications")
    defer sub.Close()
    
    ch := sub.Channel()
    for msg := range ch {
        conn.WriteMessage(websocket.TextMessage, []byte(msg.Payload))
    }
}

func sendNotification(message string) {
    rdb.Publish(ctx, "notifications", message)
}

func main() {
    http.HandleFunc("/ws", handleWebSocket)
    fmt.Println("WebSocket server with Redis running on ws://localhost:8080/ws")
    http.ListenAndServe(":8080", nil)
}
  • rdb.Publish()を使って通知をRedisに送信
  • rdb.Subscribe() でRedisから通知を受信し、WebSocketでクライアントに配信

まとめ

項目 説明
WebSocket 通知システム Goでリアルタイム通知を実装する方法
Redis Pub/Sub 異なるWebSocketサーバー間で通知を共有する方法
Redis によるスケールアウト 複数サーバーでも統一的に通知を送信

本記事では、WebSocketを活用した通知システムと、Redisを用いたWebSocketサーバーの構築方法を解説しました。
次も発展系を勉強していこうと思います!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?