func (s *Server) IsConnected(connID string) bool {
	_, found := s.getConnection(connID)
	return found
}
IsConnected returns true if the connection with that ID is connected to the Server
useful when you have defined a custom connection id generator (based on a database)
and you want to check if that connection is already connected (on multiple tabs)
package websocket
import (
	"bytes"
	"fmt"
	"net/http"
	"sync"
	"github.com/gorilla/websocket"
)
type (
	ConnectionFunc func(Connection)
	websocketRoomPayload struct {
		roomName     string
		connectionID string
	}
	websocketMessagePayload struct {
		from string
		to   string
		data []byte
	}
	Server struct {
		config Config
		ClientSource          []byte
		messageSerializer     *messageSerializer
		connections           sync.Map             
		rooms                 map[string][]string  
		mu                    sync.RWMutex         
		onConnectionListeners []ConnectionFunc
		upgrader websocket.Upgrader
	}
)
func New(cfg Config) *Server {
	cfg = cfg.Validate()
	return &Server{
		config:                cfg,
		ClientSource:          bytes.Replace(ClientSource, []byte(DefaultEvtMessageKey), cfg.EvtMessagePrefix, -1),
		messageSerializer:     newMessageSerializer(cfg.EvtMessagePrefix),
		connections:           sync.Map{},  
		rooms:                 make(map[string][]string),
		onConnectionListeners: make([]ConnectionFunc, 0),
		upgrader: websocket.Upgrader{
			HandshakeTimeout:  cfg.HandshakeTimeout,
			ReadBufferSize:    cfg.ReadBufferSize,
			WriteBufferSize:   cfg.WriteBufferSize,
			Error:             cfg.Error,
			CheckOrigin:       cfg.CheckOrigin,
			Subprotocols:      cfg.Subprotocols,
			EnableCompression: cfg.EnableCompression,
		},
	}
}
func (s *Server) Handler(w http.ResponseWriter, r *http.Request) {
	c := s.Upgrade(w, r)
	if c.Err() != nil {
		http.Error(w, fmt.Sprintf("websocket error: %v\n", c.Err()), http.StatusServiceUnavailable)
		return
	}
	for i := range s.onConnectionListeners {
		s.onConnectionListeners[i](c)
	}
	c.Wait()
}
func (s *Server) Upgrade(w http.ResponseWriter, r *http.Request) Connection {
	conn, err := s.upgrader.Upgrade(w, r, w.Header())
	if err != nil {
		return &connection{err: err}
	}
	return s.handleConnection(w, r, conn)
}
func (s *Server) addConnection(c *connection) {
	s.connections.Store(c.id, c)
}
func (s *Server) getConnection(connID string) (*connection, bool) {
	if cValue, ok := s.connections.Load(connID); ok {
		if conn, ok := cValue.(*connection); ok {
			return conn, ok
		}
	}
	return nil, false
}
func (s *Server) handleConnection(w http.ResponseWriter, r *http.Request, websocketConn UnderlineConnection) *connection {
	cid := s.config.IDGenerator(w, r)
	c := newConnection(r, s, websocketConn, cid)
	s.addConnection(c)
	s.Join(c.id, c.id)
	return c
}
func (s *Server) OnConnection(cb ConnectionFunc) {
	s.onConnectionListeners = append(s.onConnectionListeners, cb)
}