You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

95 lines
2.1 KiB
Go

package chat
import (
"fmt"
"os"
"time"
"github.com/gorilla/websocket"
)
type User struct {
Username string `json:"username"`
Token string `json:"token"`
}
type Client struct {
conn *websocket.Conn
server *Server
receivedMessages chan (WrappedMessage)
username string
id string
}
type WrappedMessage struct {
DataType string `json:"datatype"`
Data Message `json:"data"`
}
var deadline = time.Second * 60
func (c *Client) disconnect() {
dcString := fmt.Sprint("server "+c.server.Name+" ended connection with ", c.username)
delete(c.server.clients, c.id)
c.server.sendMessage(dcString)
fmt.Println(dcString)
fmt.Println(c.server.reportClients(), "clients connected to "+c.server.Name)
c.conn.WriteControl(websocket.CloseGoingAway, []byte("reconnected"), time.Now().Add(deadline))
c.conn.Close()
}
func (c *Client) pongHandler(string) error {
return c.conn.SetReadDeadline(time.Now().Add(deadline))
}
func (c *Client) awaitDisconnect() {
c.conn.SetReadDeadline(time.Now().Add(deadline))
c.conn.SetPongHandler(c.pongHandler)
for {
_, _, err := c.conn.ReadMessage()
if err != nil {
if websocket.IsUnexpectedCloseError(err, websocket.CloseNormalClosure, websocket.CloseGoingAway) {
fmt.Fprintln(os.Stderr, "Unexpected socket close error:", err.Error())
}
c.disconnect()
return
}
}
}
func (c *Client) awaitMessage() {
ticker := time.NewTicker(deadline / 2)
for {
select {
case mess := <-c.receivedMessages:
{
jsonData, ok := encodeJson(mess)
if !ok {
continue
}
if !c.sendMessage(websocket.TextMessage, jsonData) {
return
}
}
case <-ticker.C:
{
if !c.sendMessage(websocket.PingMessage, nil) {
return
}
}
}
}
}
func (c *Client) sendMessage(messageType int, data []byte) bool {
if err := c.conn.WriteMessage(messageType, data); err != nil {
if websocket.IsUnexpectedCloseError(err, websocket.CloseNormalClosure, websocket.CloseGoingAway) {
fmt.Fprintln(os.Stderr, "Unexpected socket close error:", err.Error())
c.disconnect()
}
return false
}
return true
}