start minIO, refactored files into packages
This commit is contained in:
@@ -0,0 +1,146 @@
|
||||
package wsServer
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"log"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"go-socket/packages/Enums/WsEventType"
|
||||
"go-socket/packages/cache"
|
||||
"go-socket/packages/tokens"
|
||||
"go-socket/packages/types"
|
||||
|
||||
"github.com/coder/websocket"
|
||||
"github.com/coder/websocket/wsjson"
|
||||
)
|
||||
|
||||
func ServeWsConnection(responseWriter http.ResponseWriter, request *http.Request) {
|
||||
connection, err := websocket.Accept(responseWriter, request, &websocket.AcceptOptions{
|
||||
InsecureSkipVerify: true,
|
||||
})
|
||||
if err != nil {
|
||||
log.Printf("websocket accept error: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
var user = types.User{WsConn: connection}
|
||||
var isAuthenticated bool
|
||||
var ignoreCache bool
|
||||
|
||||
defer func() { closeConnection(&user, ignoreCache) }()
|
||||
for {
|
||||
var userMessage map[string]any
|
||||
err = wsjson.Read(ctx, connection, &userMessage)
|
||||
if err != nil {
|
||||
log.Printf("read error: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
if len(userMessage) > 0 {
|
||||
if isAuthenticated {
|
||||
if !handleAuthenticatedMessage(&user, &userMessage) {
|
||||
return
|
||||
}
|
||||
} else {
|
||||
if !handleUnauthenticatedMessage(ctx, &user, &userMessage) {
|
||||
ignoreCache = true
|
||||
return
|
||||
}
|
||||
isAuthenticated = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func WsSendMessageCloseIfTimeout(user *types.User, message any) {
|
||||
if user.WsConn == nil {
|
||||
return
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
|
||||
defer cancel()
|
||||
|
||||
err := wsjson.Write(ctx, user.WsConn, message)
|
||||
if err != nil {
|
||||
if errors.Is(err, context.DeadlineExceeded) {
|
||||
closeConnection(user, false)
|
||||
}
|
||||
log.Printf("write error: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func sendToAllMessageCloseIfTimeout(message *map[string]any) {
|
||||
cache.Mu.RLock()
|
||||
users := make([]*types.User, 0, len(cache.Users))
|
||||
for _, user := range cache.Users {
|
||||
users = append(users, user)
|
||||
}
|
||||
cache.Mu.RUnlock()
|
||||
|
||||
for _, user := range users {
|
||||
WsSendMessageCloseIfTimeout(user, message)
|
||||
}
|
||||
}
|
||||
|
||||
func handleAuthenticatedMessage(user *types.User, userMessage *map[string]any) bool {
|
||||
WsSendMessageCloseIfTimeout(user, userMessage)
|
||||
return true
|
||||
}
|
||||
|
||||
func handleUnauthenticatedMessage(ctx context.Context, user *types.User, userMessage *map[string]any) bool {
|
||||
token, ok := (*userMessage)["token"].(string)
|
||||
response := types.WsEventMessage{Type: WsEventType.Authentication}
|
||||
|
||||
if !ok {
|
||||
response.Event = types.WsAuthMessage{
|
||||
Success: false,
|
||||
Error: "no token in message",
|
||||
}
|
||||
WsSendMessageCloseIfTimeout(user, response)
|
||||
return false
|
||||
}
|
||||
|
||||
userId, err := tokens.TokenValidateGetId(token)
|
||||
if err != nil {
|
||||
response.Event = types.WsAuthMessage{
|
||||
Success: false,
|
||||
Error: "invalid token",
|
||||
}
|
||||
WsSendMessageCloseIfTimeout(user, response)
|
||||
return false
|
||||
}
|
||||
|
||||
userFromCache, err := cache.CacheGetUserById(userId)
|
||||
if err != nil {
|
||||
response.Event = types.WsAuthMessage{
|
||||
Success: false,
|
||||
Error: "user not found",
|
||||
}
|
||||
WsSendMessageCloseIfTimeout(user, response)
|
||||
return false
|
||||
}
|
||||
|
||||
userFromCache.WsConn = user.WsConn
|
||||
*user = *userFromCache
|
||||
|
||||
response.Event = types.WsAuthMessage{
|
||||
Success: true,
|
||||
Error: "",
|
||||
}
|
||||
WsSendMessageCloseIfTimeout(user, response)
|
||||
return true
|
||||
}
|
||||
|
||||
func closeConnection(user *types.User, ignoreCache bool) {
|
||||
if !ignoreCache {
|
||||
cache.CacheDeleteUser(user.Id)
|
||||
}
|
||||
if user.WsConn != nil {
|
||||
user.WsConn.CloseNow()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user