func NewWebSocketClientWithDialer(dialer *websocket.Dialer, url, authToken string) (*WebSocketClient, *AppError) {
	conn, _, err := dialer.Dial(url+API_URL_SUFFIX+"/websocket", nil)
	if err != nil {
		return nil, NewAppError("NewWebSocketClient", "model.websocket_client.connect_fail.app_error", nil, err.Error(), http.StatusInternalServerError)
	}
	client := &WebSocketClient{
		url,
		url + API_URL_SUFFIX,
		url + API_URL_SUFFIX + "/websocket",
		conn,
		authToken,
		1,
		make(chan bool, 1),
		make(chan *WebSocketEvent, 100),
		make(chan *WebSocketResponse, 100),
		nil,
		nil,
	}
	client.configurePingHandling()
	client.SendMessage(WEBSOCKET_AUTHENTICATION_CHALLENGE, map[string]interface{}{"token": authToken})
	return client, nil
}
NewWebSocketClientWithDialer constructs a new WebSocket client with convenience
methods for talking to the server using a custom dialer.
package model
import (
	"encoding/json"
	"net/http"
	"time"
	"github.com/gorilla/websocket"
)
const (
	SOCKET_MAX_MESSAGE_SIZE_KB  = 8 * 1024  
	PING_TIMEOUT_BUFFER_SECONDS = 5
)
type WebSocketClient struct {
	Url                string           
	ApiUrl             string           
	ConnectUrl         string           
	Conn               *websocket.Conn  
	AuthToken          string           
	Sequence           int64            
	PingTimeoutChannel chan bool        
	EventChannel       chan *WebSocketEvent
	ResponseChannel    chan *WebSocketResponse
	ListenError        *AppError
	pingTimeoutTimer   *time.Timer
}
func NewWebSocketClient(url, authToken string) (*WebSocketClient, *AppError) {
	return NewWebSocketClientWithDialer(websocket.DefaultDialer, url, authToken)
}