@4sadly

Как сделать отправку сообщений Websocket конкретному клиенту в Go (с использованием Gorilla)+ сохранение сообщений в бд?

есть код js клиента:
let socket = new WebSocket("wss://"+location.host+"/ws");
	console.log("Attempting Connection...");

	socket.onopen = () => {
		console.log("Successfully Connected");
	};

	socket.onclose = event => {
		console.log("Socket Closed Connection: ", event);
	};

	socket.onerror = error => {
		console.log("Socket Error: ", error);
	};
	socket.onmessage = event => {
		alert(event.data);
	};

сервер go:
package main

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

var upgrader = websocket.Upgrader{
	ReadBufferSize:  1024,
	WriteBufferSize: 1024,
}

func handler(w http.ResponseWriter, r *http.Request) {
	conn, err := upgrader.Upgrade(w, r, nil)
	if err != nil {
		log.Println(err)
		return
	}
	ReadAndWrite(conn)
}
func ReadAndWrite(conn *websocket.Conn){
	for {
		messageType, msg, err := conn.ReadMessage()
		stringMsg := string(msg)
		fmt.Println("message:" , stringMsg)
		if err != nil {
			log.Println(err)
			return
		}
		answerStringMsg := "your message is: "+stringMsg
		answerByteMsg := []byte(answerStringMsg)
		if err := conn.WriteMessage(messageType , answerByteMsg); err != nil {
			log.Println(err)
			return
		}
	}
}

func main() {
	http.HandleFunc("/ws", handler)
	http.ListenAndServe(":8080", nil)
}

Какую базу данных лучше использовать для сохранения сообщений?
Как лучше будет реализовать сообщения и диалоги?
Пока что я придумал 2 способа:
1 способ: отправлять сообщение определенному пользователю, добавлять сообщение в бд, а после перезагрузки просто восстановить старые сообщения из бд
2 способ: добавлять сообщение в бд и отправлять запрос другому пользователю, чтобы он обновил данные из бд и получил новое сообщение
Если у вас есть более продуманная реализация личных сообщений и диалогов, прошу поделиться ею в комментариях, также в использовании кода клиента допускается php
  • Вопрос задан
  • 459 просмотров
Пригласить эксперта
Ответы на вопрос 3
EvgenyMamonov
@EvgenyMamonov Куратор тега Go
Senior software developer, system architect
Способ 2 создаст бОльшую нагрузку на базу, особенно если пользователей будет много.

Я бы использовал способ 1, только сначала сохранял бы сообщение в БД, а потом уже отправлял его получателю через WebSocket.

По выбору базы - тут зависит от того, какую нагрузку вы планируете выдерживать.
PostgreSQL хороший выбор, если вы ранее работали только с MySQL - тоже можете использовать.
Если же вы планируете огромные нагрузки - тогда Cassandra будет хорошим выбором.
Ответ написан
uvelichitel
@uvelichitel Куратор тега Go
habrahabr.ru/users/uvelichitel
Я делал чат на websocket (на Go и postgres). Делал по схеме 1, только еще держал в приложении кэш активных веток. Полистал github, вроде все сейчас так делают. Пишется довольно легко. Нагрузку держит удовлетворительно. Камни выплывают такие
  • Протокол websocket не гарантирует очередности доставки, логика диалогов довольно часто рвётся.
  • Современная модель мессенджеров подразумевает наличие ветвей и диалогов, в приложении это естественным образом описывается деревом. Только вот хорошо отобразить дерево(иерархическую структуру) на реляционные таблицы серебряной пули нет. Есть несколько подходов и все со своими недостатками. Альтернатива mongodb. Дерево сообщений натурально сериализуется/десериализуется JSON. Но труднее делать аналитику, сложные запросы(типа - все сообщения автора в хаб за прошлую неделю). На github большинство поделок на postgres
Ответ написан
@Abcdefgk
Собственно, я для того сюда заглядываю, чтобы прочитать какую-нибудь проблему - и её порешать.
Я сделал "приватный чат" - ну типа, 1+1, с восстановлением диалога при возвращении и т.д. - причём, в двух базах данных - MongoDB и PostgresQL. В обеих это делается запросто.
Но тебе я этого не расскажу.
(разлогиниваюсь)
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы