func (s *Socket) Write(data string) {
	s.mainChannel.Write(data)
}
Write data to the client.
package glue
import (
	"encoding/json"
	"errors"
	"fmt"
	"runtime/debug"
	"sync"
	"time"
	"github.com/Sirupsen/logrus"
	"github.com/blang/semver"
	"github.com/desertbit/glue/backend"
	"github.com/desertbit/glue/log"
	"github.com/desertbit/glue/utils"
)
const (
	Version = "1.8.0"
)
const (
	socketIDLength = 20
	pingPeriod = 30 * time.Second
	pingResponseTimeout = 7 * time.Second
	mainChannelName = "m"
	cmdLen               = 2
	cmdInit              = "in"
	cmdPing              = "pi"
	cmdPong              = "po"
	cmdClose             = "cl"
	cmdInvalid           = "iv"
	cmdDontAutoReconnect = "dr"
	cmdChannelData       = "cd"
)
var (
	ErrSocketClosed = errors.New("the socket connection is closed")
	ErrReadTimeout  = errors.New("the read timeout was reached")
)
var (
	serverVersion semver.Version
)
type ClosedChan <-chan struct{}
type OnCloseFunc func()
type OnReadFunc func(data string)
type initData struct {
	SocketID string `json:"socketID"`
}
type clientInitData struct {
	Version string `json:"version"`
}
type Socket struct {
	Value interface{}
	server *Server
	bs     backend.BackendSocket
	id            string  
	isInitialized bool
	channels    *channels
	mainChannel *Channel
	writeChan    chan string
	readChan     chan string
	isClosedChan chan struct{}
	onCloseFunc OnCloseFunc
	pingTimer         *time.Timer
	pingTimeout       *time.Timer
	sendPingMutex     sync.Mutex
	pingRequestActive bool
}
func newSocket(server *Server, bs backend.BackendSocket) *Socket {
	s := &Socket{
		server: server,
		bs:     bs,
		id:       utils.RandomString(socketIDLength),
		channels: newChannels(),
		writeChan:    bs.WriteChan(),
		readChan:     bs.ReadChan(),
		isClosedChan: make(chan struct{}),
		pingTimer:   time.NewTimer(pingPeriod),
		pingTimeout: time.NewTimer(pingResponseTimeout),
	}
	s.mainChannel = s.Channel(mainChannelName)
	bs.OnClose(s.onClose)
	s.pingTimeout.Stop()
	func() {
		s.server.socketsMutex.Lock()
		defer s.server.socketsMutex.Unlock()
		for {
			if _, ok := s.server.sockets[s.id]; !ok {
				break
			}
			s.id = utils.RandomString(socketIDLength)
		}
		s.server.sockets[s.id] = s
	}()
	go s.pingTimeoutHandler()
	go s.readLoop()
	go s.pingLoop()
	return s
}
func (s *Socket) ID() string {
	return s.id
}
func (s *Socket) IsInitialized() bool {
	return s.isInitialized
}
func (s *Socket) RemoteAddr() string {
	return s.bs.RemoteAddr()
}
func (s *Socket) UserAgent() string {
	return s.bs.UserAgent()
}
func (s *Socket) Close() {
	s.bs.Close()
}
func (s *Socket) IsClosed() bool {
	return s.bs.IsClosed()
}
func (s *Socket) OnClose(f OnCloseFunc) {
	s.onCloseFunc = f
}
func (s *Socket) ClosedChan() ClosedChan {
	return s.isClosedChan
}