本文整理匯總了Golang中code/google/com/p/go/net/websocket.Conn.SetReadDeadline方法的典型用法代碼示例。如果您正苦於以下問題:Golang Conn.SetReadDeadline方法的具體用法?Golang Conn.SetReadDeadline怎麽用?Golang Conn.SetReadDeadline使用的例子?那麽, 這裏精選的方法代碼示例或許可以為您提供幫助。您也可以進一步了解該方法所在類code/google/com/p/go/net/websocket.Conn
的用法示例。
在下文中一共展示了Conn.SetReadDeadline方法的15個代碼示例,這些例子默認根據受歡迎程度排序。您可以為喜歡或者感覺有用的代碼點讚,您的評價將有助於係統推薦出更棒的Golang代碼示例。
示例1: wsHandler
// wsHandler is a WebSocket server that handles requests from the WebSocket client in the form of:
// 1. { 'cmd': 'register', 'roomid': $ROOM, 'clientid': $CLIENT' },
// which binds the WebSocket client to a client ID and room ID.
// A client should send this message only once right after the connection is open.
// or
// 2. { 'cmd': 'send', 'msg': $MSG }, which sends the message to the other client of the room.
// It should be sent to the server only after 'regiser' has been sent.
// The message may be cached by the server if the other client has not joined.
//
// Unexpected messages will cause the WebSocket connection to be closed.
func (c *Collider) wsHandler(ws *websocket.Conn) {
var rid, cid string
registered := false
var msg wsClientMsg
loop:
for {
err := ws.SetReadDeadline(time.Now().Add(time.Duration(wsReadTimeoutSec) * time.Second))
if err != nil {
c.wsError("ws.SetReadDeadline error: "+err.Error(), ws)
break
}
err = websocket.JSON.Receive(ws, &msg)
if err != nil {
if err.Error() != "EOF" {
c.wsError("websocket.JSON.Receive error: "+err.Error(), ws)
}
break
}
switch msg.Cmd {
case "register":
if registered {
c.wsError("Duplicated register request", ws)
break loop
}
if msg.RoomID == "" || msg.ClientID == "" {
c.wsError("Invalid register request: missing 'clientid' or 'roomid'", ws)
break loop
}
if err = c.roomTable.register(msg.RoomID, msg.ClientID, ws); err != nil {
c.wsError(err.Error(), ws)
break loop
}
registered, rid, cid = true, msg.RoomID, msg.ClientID
c.dash.incrWs()
defer c.roomTable.deregister(rid, cid)
break
case "send":
if !registered {
c.wsError("Client not registered", ws)
break loop
}
if msg.Msg == "" {
c.wsError("Invalid send request: missing 'msg'", ws)
break loop
}
c.roomTable.send(rid, cid, msg.Msg)
break
default:
c.wsError("Invalid message: unexpected 'cmd'", ws)
break
}
}
// This should be unnecessary but just be safe.
ws.Close()
}
示例2: handleViewer
func handleViewer(conn *websocket.Conn) {
conn.SetReadDeadline(time.Now().Add(10 * time.Second))
var viewId string
if err := websocket.Message.Receive(conn, &viewId); err != nil {
return
}
slideId := index.getSlideId(viewId)
if slideId == "" {
return
}
listener := &slideListener{ch: make(chan int)}
registry.addListener(slideId, listener)
for {
slide := listener.get(1 * time.Minute)
if slide != 0 {
conn.SetDeadline(time.Now().Add(10 * time.Second))
if err := websocket.Message.Send(conn, fmt.Sprintf("%d", slide)); err != nil {
registry.removeListener(slideId, listener)
return
}
continue
}
if err := ping(conn); err != nil {
registry.removeListener(slideId, listener)
return
}
}
}
示例3: WaitSignal
// 從WebSocket客戶端接收信號
func WaitSignal(ws *websocket.Conn, notify_stop_chan chan<- bool, timer **time.Timer,
pause *bool, resume_chan chan bool, elapsed *int64, mutex *sync.Mutex) {
var start_time int64
var end_time int64
for {
// 設置Read Deadline為24小時
ws.SetReadDeadline(time.Now().Add(86400 * time.Second))
buf := make([]byte, 8)
_, err := ws.Read(buf)
if err != nil {
log.Println("Playback Server: Read data from client failed: ", err)
mutex.Lock()
if (*timer) != nil {
(*timer).Reset(time.Duration(time.Nanosecond))
}
mutex.Unlock()
notify_stop_chan <- true
goto end
}
data, _ := strconv.Atoi(string(recorder.GetValidByte(buf)))
if data == 800 { // 關閉
// 如果執行了暫停,首先取消暫停
if *pause == true {
resume_chan <- true
}
// 取消定時器,發送結束信號
mutex.Lock()
if (*timer) != nil {
(*timer).Reset(time.Duration(time.Nanosecond))
}
mutex.Unlock()
notify_stop_chan <- true
goto end
} else if data == 801 { // 暫停
if *pause == false {
// 設置暫停標誌,記錄暫停開始時間
*pause = true
start_time = getNowMillisecond()
}
} else if data == 802 { // 恢複
if *pause == true {
// 記錄暫停結束時間,向恢複的channel發送信號
end_time = getNowMillisecond()
*elapsed += (end_time - start_time)
*pause = false
resume_chan <- true
}
}
}
end:
ws.Close()
}
示例4: newConn
func (server *Server) newConn(socket *ws.Conn) {
readyChan := make(chan bool, 1)
stopChan := make(chan bool, 1)
if err := socket.SetReadDeadline(time.Now().Add(30 * time.Second)); err != nil {
if err := socket.Close(); err != nil {
// ...
}
}
server.waitGroup.Add(1)
defer server.waitGroup.Done()
conn := &Conn{
Socket: socket,
Server: server,
messageChan: make(chan *Message, 50),
readyChan: readyChan,
stopChan: stopChan,
}
doneChan := make(chan bool)
go func() {
defer close(doneChan)
state := ConnState(readHelo).Timeout(10 * time.Second)
for state != nil {
next, err := state(conn)
if err != nil {
_ = conn.Close()
return
}
state = next
}
}()
for ok := true; ok; {
select {
case <-readyChan:
server.addConn(conn)
case <-conn.stopChan:
server.removeConn(conn)
if err := conn.Close(); err != nil {
return
}
ok = false
case <-conn.messageChan:
// TODO: Forward messages to the IR.
continue
case _, ok = <-doneChan:
}
}
}
示例5: handlePresenter
func handlePresenter(conn *websocket.Conn) {
conn.SetReadDeadline(time.Now().Add(10 * time.Second))
var slideIdParam string
if err := websocket.Message.Receive(conn, &slideIdParam); err != nil {
return
}
slideId, _ := index.getIdPair(slideIdParam)
if slideId == "" {
return
}
for {
var slide string
conn.SetDeadline(time.Now().Add(15 * time.Minute))
if err := websocket.Message.Receive(conn, &slide); err != nil {
return
}
curSlide, _ := strconv.Atoi(slide)
registry.setSlide(slideId, curSlide)
}
}
示例6: SubscribeHandle
// Subscriber Handle is the websocket handle for sub request.
func SubscribeHandle(ws *websocket.Conn) {
addr := ws.Request().RemoteAddr
params := ws.Request().URL.Query()
// get subscriber key
key := params.Get("key")
if key == "" {
ws.Write(ParamReply)
Log.Warn("<%s> key param error", addr)
return
}
// get heartbeat second
heartbeatStr := params.Get("heartbeat")
i, err := strconv.Atoi(heartbeatStr)
if err != nil {
ws.Write(ParamReply)
Log.Error("<%s> user_key:\"%s\" heartbeat argument error(%s)", addr, key, err)
return
}
if i < minHearbeatSec {
ws.Write(ParamReply)
Log.Warn("<%s> user_key:\"%s\" heartbeat argument error, less than %d", addr, key, minHearbeatSec)
return
}
heartbeat := i + delayHeartbeatSec
token := params.Get("token")
Log.Info("<%s> subscribe to key = %s, heartbeat = %d, token = %s", addr, key, heartbeat, token)
// fetch subscriber from the channel
c, err := UserChannel.Get(key, true)
if err != nil {
ws.Write(ChannelReply)
Log.Error("<%s> user_key:\"%s\" can't get a channel error(%s)", addr, key, err)
return
}
// auth token
if ok := c.AuthToken(key, token); !ok {
ws.Write(AuthReply)
Log.Error("<%s> user_key:\"%s\" auth token \"%s\" failed", addr, key, token)
return
}
// add a conn to the channel
connElem, err := c.AddConn(key, &Connection{Conn: ws, Proto: WebsocketProto})
if err != nil {
Log.Error("<%s> user_key:\"%s\" add conn error(%s)", addr, key, err)
return
}
// blocking wait client heartbeat
reply := ""
begin := time.Now().UnixNano()
end := begin + Second
for {
// more then 1 sec, reset the timer
if end-begin >= Second {
if err = ws.SetReadDeadline(time.Now().Add(time.Second * time.Duration(heartbeat))); err != nil {
Log.Error("<%s> user_key:\"%s\" websocket.SetReadDeadline() error(%s)", addr, key, err)
break
}
begin = end
}
if err = websocket.Message.Receive(ws, &reply); err != nil {
Log.Error("<%s> user_key:\"%s\" websocket.Message.Receive() error(%s)", addr, key, err)
break
}
if reply == Heartbeat {
if _, err = ws.Write(HeartbeatReply); err != nil {
Log.Error("<%s> user_key:\"%s\" write heartbeat to client error(%s)", addr, key, err)
break
}
Log.Debug("<%s> user_key:\"%s\" receive heartbeat", addr, key)
} else {
Log.Warn("<%s> user_key:\"%s\" unknown heartbeat protocol", addr, key)
break
}
end = time.Now().UnixNano()
}
// remove exists conn
if err := c.RemoveConn(key, connElem); err != nil {
Log.Error("<%s> user_key:\"%s\" remove conn error(%s)", addr, key, err)
}
return
}
示例7: Subscribe
func Subscribe(ws *websocket.Conn) {
var (
result = map[string]interface{}{}
key string
)
defer recoverFunc()
// cleanup on server side
//defer func() {
// if err := ws.Close(); err != nil {
// Log.Printf("wc.Close() failed (%s)", err.Error())
// }
//}()
// set read deadline
err := ws.SetReadDeadline(time.Now().Add(time.Duration(Conf.LongpollingTimeout) * time.Second))
if err != nil {
Log.Printf("ws.SetReadDeadline() failed (%s)", err.Error())
return
}
// get key
if err = websocket.Message.Receive(ws, &key); err != nil {
Log.Printf("websocket.Message.Receive failed (%s)", err.Error())
return
}
// Auth
if !pusher.Auth(key) {
if err = responseWriter(ws, AuthErr, result); err != nil {
Log.Printf("responseWriter failed (%s)", err.Error())
}
return
}
// Generate Key
key = pusher.Key(key)
Log.Printf("Client (%s) subscribe to key %s", ws.Request().RemoteAddr, key)
// check multi cli connected
if Conf.MaxSubscriberPerKey > 0 {
ok, err := multiCliCheck(key)
if err != nil {
if err = responseWriter(ws, InternalErr, result); err != nil {
Log.Printf("responseWriter failed (%s)", err.Error())
}
return
}
defer func() {
if err = RedisDecr(ConnectedKey, key); err != nil {
Log.Printf("RedisDecr(\"%s\", \"%s\") failed (%s)", ConnectedKey, key, err.Error())
}
}()
if !ok {
if err = responseWriter(ws, MultiCliErr, result); err != nil {
Log.Printf("responseWriter failed (%s)", err.Error())
}
return
}
}
// redis routine for receive pub message or error
redisC, psc, err := RedisSub(key)
if err != nil {
Log.Printf("RedisSub(\"%s\") failed (%s)", key, err.Error())
if err = responseWriter(ws, InternalErr, result); err != nil {
Log.Printf("responseWriter failed (%s)", err.Error())
}
return
}
// unsub redis
defer func() {
if err := RedisUnSub(key, psc); err != nil {
Log.Printf("RedisUnSub(\"%s\", psc) failed (%s)", key, err.Error())
}
}()
// create a routine wait for client read(only closed or error) return a channel
netC := netRead(ws)
for {
select {
case err := <-netC:
Log.Printf("websocket.Message.Receive faild (%s)", err.Error())
return
case msg := <-redisC:
if rmsg, ok := msg.(string); ok {
result["data"] = rmsg
if err = responseWriter(ws, OK, result); err != nil {
Log.Printf("responseWriter failed (%s)", err.Error())
// Restore the unsent message
if err = RedisRestore(key, rmsg); err != nil {
Log.Printf("RedisRestore(\"%s\", \"%s\") failed", key, msg)
return
}
return
}
} else if err, ok := msg.(error); ok {
// DEBUG
Log.Printf("Subscribe() failed (%s)", err.Error())
return
//.........這裏部分代碼省略.........
示例8: SubscribeHandle
func SubscribeHandle(ws *websocket.Conn) {
defer recoverFunc()
params := ws.Request().URL.Query()
// get subscriber key
key := params.Get("key")
// get lastest message id
midStr := params.Get("mid")
mid, err := strconv.ParseInt(midStr, 10, 64)
if err != nil {
Log.Printf("mid argument error (%s)", err.Error())
return
}
// get heartbeat second
heartbeat := Conf.HeartbeatSec
heartbeatStr := params.Get("heartbeat")
if heartbeatStr != "" {
i, err := strconv.Atoi(heartbeatStr)
if err != nil {
Log.Printf("heartbeat argument error (%s)", err.Error())
return
}
heartbeat = i
}
heartbeat *= 2
if heartbeat <= 0 {
Log.Printf("heartbeat argument error, less than 0")
return
}
// get auth token
token := params.Get("token")
Log.Printf("client %s subscribe to key = %s, mid = %d, token = %s, heartbeat = %d", ws.Request().RemoteAddr, key, mid, token, heartbeat)
// fetch subscriber from the channel
c, err := channel.Get(key)
if err != nil {
if Conf.Auth == 0 {
c, err = channel.New(key)
if err != nil {
Log.Printf("device %s: can't create channle", key)
return
}
} else {
Log.Printf("device %s: can't get a channel (%s)", key, err.Error())
return
}
}
// auth
if Conf.Auth == 1 {
if err = c.AuthToken(token, key); err != nil {
Log.Printf("device %s: auth token failed \"%s\" (%s)", key, token, err.Error())
return
}
}
// send stored message, and use the last message id if sent any
if err = c.SendMsg(ws, mid, key); err != nil {
Log.Printf("device %s: send offline message failed (%s)", key, err.Error())
return
}
// add a conn to the channel
if err = c.AddConn(ws, mid, key); err != nil {
Log.Printf("device %s: add conn failed (%s)", key, err.Error())
return
}
// remove exists conn
defer func() {
if err := c.RemoveConn(ws, mid, key); err != nil {
Log.Printf("device %s: remove conn failed (%s)", key, err.Error())
}
}()
// blocking wait client heartbeat
reply := ""
for {
ws.SetReadDeadline(time.Now().Add(time.Second * time.Duration(heartbeat)))
if err = websocket.Message.Receive(ws, &reply); err != nil {
Log.Printf("websocket.Message.Receive() failed (%s)", err.Error())
return
}
if reply == heartbeatMsg {
if _, err = ws.Write(heartbeatBytes); err != nil {
Log.Printf("device %s: write heartbeat to client failed (%s)", key, err.Error())
return
}
Log.Printf("device %s: receive heartbeat", key)
} else {
Log.Printf("device %s: unknown heartbeat protocol", key)
return
}
}
//.........這裏部分代碼省略.........
示例9: SubscribeHandle
// Subscriber Handle is the websocket handle for sub request
func SubscribeHandle(ws *websocket.Conn) {
params := ws.Request().URL.Query()
// get subscriber key
key := params.Get("key")
// get lastest message id
midStr := params.Get("mid")
mid, err := strconv.ParseInt(midStr, 10, 64)
if err != nil {
LogError(LogLevelErr, "mid argument error (%s)", err.Error())
return
}
// get heartbeat second
heartbeat := Conf.HeartbeatSec
heartbeatStr := params.Get("heartbeat")
if heartbeatStr != "" {
i, err := strconv.Atoi(heartbeatStr)
if err != nil {
LogError(LogLevelErr, "heartbeat argument error (%s)", err.Error())
return
}
heartbeat = i
}
heartbeat *= 2
if heartbeat <= 0 {
LogError(LogLevelErr, "heartbeat argument error, less than 0")
return
}
// get auth token
token := params.Get("token")
LogError(LogLevelInfo, "client:%s subscribe to key = %s, mid = %d, token = %s, heartbeat = %d", ws.Request().RemoteAddr, key, mid, token, heartbeat)
// fetch subscriber from the channel
c, err := channel.Get(key)
if err != nil {
if Conf.Auth == 0 {
c, err = channel.New(key)
if err != nil {
LogError(LogLevelErr, "device:%s can't create channle (%s)", key, err.Error())
return
}
} else {
LogError(LogLevelErr, "device:%s can't get a channel (%s)", key, err.Error())
return
}
}
// auth
if Conf.Auth == 1 {
if err = c.AuthToken(token, key); err != nil {
LogError(LogLevelErr, "device:%s auth token failed \"%s\" (%s)", key, token, err.Error())
return
}
}
// send first heartbeat to tell client service is ready for accept heartbeat
if _, err = ws.Write(heartbeatBytes); err != nil {
LogError(LogLevelErr, "device:%s write first heartbeat to client failed (%s)", key, err.Error())
return
}
// send stored message, and use the last message id if sent any
if err = c.SendMsg(ws, mid, key); err != nil {
LogError(LogLevelErr, "device:%s send offline message failed (%s)", key, err.Error())
return
}
// add a conn to the channel
if err = c.AddConn(ws, mid, key); err != nil {
LogError(LogLevelErr, "device:%s add conn failed (%s)", key, err.Error())
return
}
// blocking wait client heartbeat
reply := ""
begin := time.Now().UnixNano()
end := begin + oneSecond
for {
// more then 1 sec, reset the timer
if end-begin >= oneSecond {
if err = ws.SetReadDeadline(time.Now().Add(time.Second * time.Duration(heartbeat))); err != nil {
LogError(LogLevelErr, "device:%s websocket.SetReadDeadline() failed (%s)", key, err.Error())
break
}
begin = end
}
if err = websocket.Message.Receive(ws, &reply); err != nil {
LogError(LogLevelErr, "device:%s websocket.Message.Receive() failed (%s)", key, err.Error())
break
}
if reply == heartbeatMsg {
if _, err = ws.Write(heartbeatBytes); err != nil {
LogError(LogLevelErr, "device:%s write heartbeat to client failed (%s)", key, err.Error())
break
//.........這裏部分代碼省略.........
示例10: chat
func (c *WebSocket) chat(ws *websocket.Conn) {
//ws.SetReadDeadline(time.Now().Add(3 * time.Second))
var register RegisterMsg
var err error
if err = websocket.JSON.Receive(ws, ®ister); err != nil {
ERROR.Println(err)
return
}
if register.Type != LoginMsgType || register.Id == 0 {
ws.Write(LoginAlterJsonBytes)
ERROR.Println("please login first")
return
}
if register.DevType != 0x1 && register.DevType != 0x2 {
ws.Write(UnknownDevicesJsonBytes)
ERROR.Println("unknown devices")
return
}
if _, err = ws.Write(OkJsonBytes); err != nil {
ERROR.Println(err)
return
}
client := NewChatClient(ws, register.Id, register.DevType)
if err = hub.AddClient(client); err != nil {
ERROR.Println(err)
if redirect, ok := err.(*pmsg.RedirectError); ok {
client.Redirect(redirect.HubId)
}
return
}
go client.SendMsgLoop()
defer func() {
if err := recover(); err != nil {
ERROR.Println(err)
}
client.CloseChannel()
hub.RemoveClient(client)
}()
var msgType byte = pmsg.RouteMsgType
for {
var msg Msg
ws.SetReadDeadline(time.Now().Add(1 * time.Minute))
if err := websocket.JSON.Receive(ws, &msg); err != nil {
if err == io.EOF {
INFO.Println(ws.Request().RemoteAddr, "closed")
} else {
ERROR.Println(err)
}
return
}
if msg.SourceType == 1 && (msg.To == nil || *msg.To == 0) {
ws.Write(InvaildParameters)
return
}
if msg.SourceType == 3 && (msg.Gid == nil || *msg.Gid == 0) {
ws.Write(InvaildParameters)
return
}
if err = validateMsg(&msg); err != nil {
ERROR.Println(err)
ws.Write(JsonFormatErrorJsonBytes)
return
}
now := time.Now()
switch msg.Type {
case PingMsgType:
//ping, don't reply
continue
case TokenRegisterMsgType:
if msg.MsgId == "" || msg.Token == nil {
ws.Write(ErrorMsgIdJsonFormatJsonBytes)
return
}
reply := &ReplyMsg{
Type: ReplyMsgType,
Time: now.UnixNano() / 1000000,
MsgId: msg.MsgId,
Code: 0,
}
if err = registerToken(client.clientId, msg.Dev, *msg.Token); err != nil {
reply.Code = -1
reply.Msg = err.Error()
ws.Write(reply.Bytes())
return
}
client.SendMsg(reply)
continue
case TokenUnregisterMsgType:
if msg.MsgId == "" || msg.Token == nil {
ws.Write(ErrorMsgIdJsonFormatJsonBytes)
return
}
reply := &ReplyMsg{
Type: ReplyMsgType,
Time: now.UnixNano() / 1000000,
MsgId: msg.MsgId,
//.........這裏部分代碼省略.........
示例11: WSSendRecv
// WSSendRecv is the handler for websocket client connections. It loops
// forever (until disconnected), reading JSON-RPC requests and sending
// sending responses and notifications.
func (s *server) WSSendRecv(ws *websocket.Conn, remoteAddr string, authenticated bool) {
// Clear the read deadline set before the websocket hijacked
// the connection.
ws.SetReadDeadline(time.Time{})
// Add client context so notifications duplicated to each
// client are received by this client.
recvQuit := make(chan struct{})
sendQuit := make(chan struct{})
cc := clientContext{
send: make(chan []byte, 1), // buffer size is number of initial notifications
quit: make(chan struct{}),
}
go func() {
select {
case <-recvQuit:
case <-sendQuit:
}
log.Infof("Disconnected websocket client %s", remoteAddr)
close(cc.quit)
}()
log.Infof("New websocket client %s", remoteAddr)
NotifyBtcdConnection(cc.send) // TODO(jrick): clients should explicitly request this.
addClient <- cc
// received passes all received messages from the currently connected
// frontend to the for-select loop. It is closed when reading a
// message from the websocket connection fails (presumably due to
// a disconnected client).
recvQueueIn := make(chan string)
// Receive messages from websocket and send across jsonMsgs until
// connection is lost
go func() {
for {
var m string
if err := websocket.Message.Receive(ws, &m); err != nil {
select {
case <-sendQuit:
// Do not log error.
default:
if err != io.EOF {
log.Warnf("Websocket receive failed from client %s: %v",
remoteAddr, err)
}
}
close(recvQueueIn)
close(recvQuit)
return
}
recvQueueIn <- m
}
}()
// Manage queue of received messages for LIFO processing.
recvQueueOut := make(chan string)
go stringQueue(recvQueueIn, recvQueueOut, cc.quit)
badAuth := make(chan struct{})
sendResp := make(chan []byte)
go func() {
out:
for m := range recvQueueOut {
resp, err := s.ReplyToFrontend([]byte(m), true, authenticated)
if err == ErrBadAuth {
select {
case badAuth <- struct{}{}:
case <-cc.quit:
}
break out
}
// Authentication passed.
authenticated = true
select {
case sendResp <- resp:
case <-cc.quit:
break out
}
}
close(sendResp)
}()
const deadline time.Duration = 2 * time.Second
out:
for {
var m []byte
var ok bool
select {
case <-badAuth:
// Bad auth. Disconnect.
log.Warnf("Disconnecting unauthorized websocket client %s", remoteAddr)
//.........這裏部分代碼省略.........
示例12: Chat
func Chat(ws *websocket.Conn) {
ws.SetReadDeadline(time.Now().Add(15 * time.Second))
var loginMsg LoginMsg
var user *UserInfo
var err error
if err = websocket.JSON.Receive(ws, &loginMsg); err != nil {
ERROR.Println(err)
return
}
if loginMsg.Type != LoginMsgType || loginMsg.Id == 0 {
ws.Write(LoginAlterJsonBytes)
ERROR.Println("please login first")
return
}
if loginMsg.DevType != 0x1 && loginMsg.DevType != 0x2 {
ws.Write(UnknownDevicesJsonBytes)
ERROR.Println("unknown devices")
return
}
if user, err = GetUserById(loginMsg.Id); err != nil {
ws.Write(LoginFailJsonBytes)
ERROR.Println(err)
return
}
if user.Password != loginMsg.Password {
ERROR.Println("login fail")
ws.Write(LoginFailJsonBytes)
return
}
if _, err = ws.Write(OkJsonBytes); err != nil {
ERROR.Println(err)
return
}
client := NewChatClient(ws, user.Id, loginMsg.DevType)
if err = hub.AddClient(client); err != nil {
ERROR.Println(err)
if redirect, ok := err.(*pmsg.RedirectError); ok {
client.Redirect(redirect.HubId)
}
return
}
go client.SendMsgLoop()
defer func() {
if err := recover(); err != nil {
ERROR.Println(err)
}
client.CloseChannel()
hub.RemoveClient(client)
}()
var pmsgType byte = pmsg.RouteMsgType
for {
message := map[string]json.RawMessage{}
ws.SetReadDeadline(time.Now().Add(1 * time.Minute))
if err := websocket.JSON.Receive(ws, &message); err != nil {
if err == io.EOF {
INFO.Println(ws.Request().RemoteAddr, "closed")
} else {
ERROR.Println(err)
}
return
}
var msgId string
var msgType byte
if err = ParseField(message, "type", &msgType); err != nil {
ws.Write(UnknownDevicesJsonBytes)
ERROR.Println("parse type error.", err)
return
}
if err = ParseField(message, "id", &msgId); err != nil {
ws.Write(UnknownDevicesJsonBytes)
ERROR.Println("parse msgId error.", err)
return
}
if msgType == PingMsgType {
//ping, don't reply
continue
}
var msg *Msg
if msg, err = ConvertMsg(message); err != nil {
ws.Write(UnknownDevicesJsonBytes)
ERROR.Println(err)
return
}
if msgId == "" {
ws.Write(ErrorMsgIdJsonFormatJsonBytes)
ERROR.Println("msgId is empty")
return
}
msg.From = client.clientId
if len(user.Name) > 0 {
msg.Sender = &user.Name
//.........這裏部分代碼省略.........
示例13: SubscribeHandle
// Subscriber Handle is the websocket handle for sub request.
func SubscribeHandle(ws *websocket.Conn) {
params := ws.Request().URL.Query()
// get subscriber key
key := params.Get("key")
if key == "" {
Log.Warn("client:%s key param error", ws.Request().RemoteAddr)
return
}
// get heartbeat second
heartbeat := Conf.HeartbeatSec
heartbeatStr := params.Get("heartbeat")
if heartbeatStr != "" {
i, err := strconv.Atoi(heartbeatStr)
if err != nil {
Log.Error("user_key:\"%s\" heartbeat argument error (%s)", key, err.Error())
return
}
heartbeat = i
}
heartbeat *= 2
if heartbeat <= 0 {
Log.Error("user_key \"%s\" heartbeat argument error, less than 0", key)
return
}
token := params.Get("token")
Log.Info("client:%s subscribe to key = %s, heartbeat = %d, token = %s", ws.Request().RemoteAddr, key, heartbeat, token)
// fetch subscriber from the channel
c, err := UserChannel.Get(key)
if err != nil {
Log.Error("user_key:\"%s\" can't get a channel (%s)", key, err.Error())
return
}
// auth token
if Conf.Auth == 1 {
if err = c.AuthToken(token, key); err != nil {
Log.Error("user_key:\"%s\" auth token failed (%s)", key, err.Error())
return
}
}
// add a conn to the channel
connElem, err := c.AddConn(ws, key)
if err != nil {
Log.Error("user_key:\"%s\" add conn failed (%s)", key, err.Error())
return
}
// send first heartbeat to tell client service is ready for accept heartbeat
if _, err = ws.Write(websocketHeartbeatReply); err != nil {
Log.Error("user_key:\"%s\" write first heartbeat to client failed (%s)", key, err.Error())
if err := c.RemoveConn(connElem, key); err != nil {
Log.Error("user_key:\"%s\" remove conn failed (%s)", key, err.Error())
}
return
}
// blocking wait client heartbeat
reply := ""
begin := time.Now().UnixNano()
end := begin + Second
for {
// more then 1 sec, reset the timer
if end-begin >= Second {
if err = ws.SetReadDeadline(time.Now().Add(time.Second * time.Duration(heartbeat))); err != nil {
Log.Error("user_key:\"%s\" websocket.SetReadDeadline() failed (%s)", key, err.Error())
break
}
begin = end
}
if err = websocket.Message.Receive(ws, &reply); err != nil {
Log.Error("user_key:\"%s\" websocket.Message.Receive() failed (%s)", key, err.Error())
break
}
if reply == Heartbeat {
if _, err = ws.Write(websocketHeartbeatReply); err != nil {
Log.Error("user_key:\"%s\" write heartbeat to client failed (%s)", key, err.Error())
break
}
Log.Debug("user_key:\"%s\" receive heartbeat", key)
} else {
Log.Warn("user_key:\"%s\" unknown heartbeat protocol", key)
break
}
end = time.Now().UnixNano()
}
// remove exists conn
if err := c.RemoveConn(connElem, key); err != nil {
//.........這裏部分代碼省略.........
示例14: walletReqsNotifications
// walletReqsNotifications is the handler function for websocket
// connections from a btcwallet instance. It reads messages from wallet and
// sends back replies, as well as notififying wallets of chain updates.
func (s *rpcServer) walletReqsNotifications(ws *websocket.Conn, authenticated bool) {
// Clear the read deadline that was set before the websocket hijacked
// the connection.
ws.SetReadDeadline(timeZeroVal)
// Add wallet notification channel so this handler receives btcd chain
// notifications.
n := make(ntfnChan)
rc := &requestContexts{
authenticated: authenticated,
txRequests: make(map[string]struct{}),
spentRequests: make(map[btcwire.OutPoint]struct{}),
minedTxRequests: make(map[btcwire.ShaHash]struct{}),
}
s.AddWalletListener(n, rc)
defer s.RemoveWalletListener(n)
// Channel for responses.
r := make(chan *btcjson.Reply)
// Channels for websocket handlers.
disconnected := make(chan struct{})
hc := handlerChans{
n: n,
disconnected: disconnected,
}
// msgs is a channel for all messages received over the websocket.
msgs := make(chan string)
// Receive messages from websocket and send across reqs until the
// connection is lost.
go func() {
for {
select {
case <-s.quit:
return
default:
var m string
if err := websocket.Message.Receive(ws, &m); err != nil {
// Only close disconnected if not closed yet.
select {
case <-disconnected:
// nothing
default:
close(disconnected)
}
return
}
msgs <- m
}
}
}()
for {
select {
case <-s.quit:
// Server closed. Closing disconnected signals handlers to stop
// and flushes all channels handlers may write to.
select {
case <-disconnected:
// nothing
default:
close(disconnected)
}
case <-disconnected:
for {
select {
case <-msgs:
case <-r:
case <-n:
default:
return
}
}
case m := <-msgs:
// This function internally spawns a new goroutine to
// the handle request after validating authentication.
// Responses and notifications are read by channels in
// this for-select loop.
if !rc.disconnecting {
err := s.websocketJSONHandler(r, hc, m)
if err == ErrBadAuth {
rc.disconnecting = true
close(disconnected)
ws.Close()
}
}
case response := <-r:
// Marshal and send response.
mresp, err := json.Marshal(response)
//.........這裏部分代碼省略.........
示例15: SubscribeHandle
// Subscriber Handle is the websocket handle for sub request.
func SubscribeHandle(ws *websocket.Conn) {
addr := ws.Request().RemoteAddr
params := ws.Request().URL.Query()
// get subscriber key
key := params.Get("key")
if key == "" {
ws.Write(ParamReply)
logger.Warnf("<%s> key param error", addr)
return
}
// get heartbeat second
heartbeatStr := params.Get("heartbeat")
i, err := strconv.Atoi(heartbeatStr)
if err != nil {
ws.Write(ParamReply)
logger.Errorf("<%s> user_key:\"%s\" heartbeat argument error(%s)", addr, key, err)
return
}
if i < minHearbeatSec {
ws.Write(ParamReply)
logger.Warnf("<%s> user_key:\"%s\" heartbeat argument error, less than %d", addr, key, minHearbeatSec)
return
}
heartbeat := i + delayHeartbeatSec
token := params.Get("token")
version := params.Get("ver")
logger.Tracef("<%s> subscribe to key = %s, heartbeat = %d, token = %s, version = %s", addr, key, heartbeat, token, version)
// fetch subscriber from the channel
c, err := UserChannel.Get(key, true)
if err != nil {
ws.Write(ChannelReply)
logger.Errorf("<%s> user_key:\"%s\" can't get a channel error(%s)", addr, key, err)
return
}
// auth token
if ok := c.AuthToken(key, token); !ok {
ws.Write(AuthReply)
logger.Errorf("<%s> user_key:\"%s\" auth token \"%s\" failed", addr, key, token)
return
}
// add a conn to the channel
connElem, err := c.AddConn(key, &Connection{Conn: ws, Proto: WebsocketProto, Version: version})
if err != nil {
logger.Errorf("<%s> user_key:\"%s\" add conn error(%s)", addr, key, err)
return
}
//分割出userid sessionid type {userId}_{browser}-{version}-{rn}@{xx}
//添加會話記錄sessionID
var sessionId string = ""
strs := strings.Split(key, "@")
isAPP := strings.HasSuffix(key, "@app")
if len(strs) > 0 && !isAPP {
sessionId = strs[0]
tmps := strings.Split(strs[0], "_")
if len(tmps) > 1 {
userId := tmps[0] //此user不一定時userid 若用戶為登錄則時應用製定的任意數
sessionType := ""
types := strings.Split(tmps[1], "-")
if len(types) > 0 {
sessionType = types[0]
}
sessionObj := &session.Session{
Id: sessionId,
Type: sessionType,
UserId: userId,
State: session.SESSION_STATE_INIT,
Created: time.Now().Local(),
Updated: time.Now().Local(),
}
session.CreatSession(sessionObj)
}
}
//開始定時更新會話更新時間
var tickerFlagStop = make(chan bool, 1)
if !isAPP {
go session.TickerTaskUpdateSession(sessionId, tickerFlagStop)
}
// blocking wait client heartbeat
reply := ""
begin := time.Now().UnixNano()
end := begin + Second
for {
// more then 1 sec, reset the timer
if end-begin >= Second {
if err = ws.SetReadDeadline(time.Now().Add(time.Second * time.Duration(heartbeat))); err != nil {
logger.Errorf("<%s> user_key:\"%s\" websocket.SetReadDeadline() error(%s)", addr, key, err)
break
}
begin = end
}
if err = websocket.Message.Receive(ws, &reply); err != nil {
logger.Errorf("<%s> user_key:\"%s\" websocket.Message.Receive() error(%s)", addr, key, err)
//.........這裏部分代碼省略.........