zoukankan      html  css  js  c++  java
  • go 随websocket存亡的token

     1 package token
     2 
     3 import (
     4     "crypto/md5"
     5     "fmt"
     6     "io"
     7     "math/rand"
     8     "sync"
     9     "time"
    10 )
    11 
    12 type User struct {
    13     ID    string
    14     Timer *time.Timer
    15 }
    16 
    17 var Token map[string]*User = make(map[string]*User)
    18 var maxLiveTime time.Duration = time.Hour * 24 // Token更新时间暂定为24小时
    19 var lock sync.RWMutex
    20 
    21 const randStringLen = 16
    22 
    23 func randString() string {
    24     str := make([]byte, randStringLen)
    25     for i := 0; i < randStringLen; i++ {
    26         str[i] = byte(rand.Uint32() & ((1 << 7) - 1))
    27     }
    28     return string(str)
    29 }
    30 
    31 func New(userID string, token *string, writeToken func()) {
    32     lock.Lock()
    33     delete(Token, *token)
    34     hash := md5.New()
    35     io.WriteString(hash, userID)
    36     io.WriteString(hash, time.Now().String())
    37     *token = fmt.Sprintf("%x", hash.Sum(nil))
    38     timer := time.AfterFunc(maxLiveTime, func() { New(userID, token, writeToken) })
    39     Token[*token] = &User{
    40         ID:    userID,
    41         Timer: timer,
    42     }
    43     lock.Unlock()
    44     writeToken()
    45 }
    46 
    47 func Del(token string) {
    48     lock.Lock()
    49     defer lock.Unlock()
    50     user := Token[token]
    51     user.Timer.Stop()
    52     delete(Token, token)
    53 }
    54 
    55 func GetUser(token string) (user *User, exisToken bool) {
    56     lock.RLock()
    57     defer lock.RUnlock()
    58     user, exisToken = Token[token]
    59     return user, exisToken
    60 }
    token
     1 package Network
     2 
     3 import (
     4     "logs"
     5     "time"
     6     "token"
     7 
     8     "github.com/gorilla/websocket"
     9 )
    10 
    11 type ClientData struct {
    12     conn  *websocket.Conn
    13     token string
    14 }
    15 
    16 var wsClients = make(map[string]ClientData)
    17 
    18 // 是否在线
    19 func isOnline(clientID string) bool {
    20     lock.RLock()
    21     _, isOnline := wsClients[clientID]
    22     lock.RUnlock()
    23     return isOnline
    24 }
    25 
    26 // --------------------------------------------- 连接管理部分
    27 
    28 // 增加WebSocket连接
    29 func addClient(clientID string, con *websocket.Conn) (canAdd bool) {
    30 
    31     if isOnline(clientID) {
    32         writeResponseToClient(clientID, ServerResponse{
    33             Method:  "/wsLogin",
    34             Code:    noticeForceQuit,
    35             Message: mForceQuit,
    36             Result:  nil,
    37         })
    38         deleteClient(clientID)
    39         time.Sleep(time.Millisecond) // 如果不睡眠或者睡眠时间太短,两个连接都会被同时关掉
    40         logs.Print(clientID, mForceQuit)
    41         addConnection(clientID, con)
    42         return false
    43     }
    44     addConnection(clientID, con)
    45     return true
    46 }
    47 
    48 func addConnection(clientID string, con *websocket.Conn) {
    49     clientData := ClientData{
    50         conn:  con,
    51         token: "",
    52     }
    53     token.New(clientID, &clientData.token, func() { //此函数用于每次token变化后将token写回客户端
    54         //更新完client后才能writeResponse,注意死锁
    55         lock.Lock()
    56         wsClients[clientID] = clientData
    57         lock.Unlock()
    58         writeResponseToClient(clientID, ServerResponse{
    59             Code:    Success,
    60             Method:  "/token",
    61             Message: "",
    62             Result:  map[string]string{"Token": clientData.token},
    63         })
    64     })
    65 }
    66 
    67 // 获取客户端连接
    68 func getClient(clientID string) (clientConn *websocket.Conn, isOnline bool) {
    69 
    70     lock.RLock()
    71     clientData, ok := wsClients[clientID]
    72     lock.RUnlock()
    73     return clientData.conn, ok
    74 }
    75 
    76 // 删除WebSocket连接
    77 func deleteClient(clientID string) {
    78     clientData, ok := wsClients[clientID]
    79     if !ok {
    80         return
    81     }
    82     lock.Lock()
    83     clientData.conn.Close()
    84     token.Del(clientData.token)
    85     delete(wsClients, clientID)
    86     lock.Unlock()
    87 }
    websocket连接管理

    因为登录是用websocket,返回前端token的也是websoket(websoket验证成功后马上返回token),所以websocket在,token就在,websocket关闭连接后token也结束了生命周期

  • 相关阅读:
    设计模式(十)—— 装饰者模式
    设计模式(九)—— 组合模式
    设计模式(八)—— 桥接模式
    设计模式(七)—— 适配器模式
    LINQ to XML
    设计模式(六)—— 单例模式
    设计模式(五)—— 原型模式
    Asp.Net程序目录下文件夹或文件操作导致Session失效的解决方案
    基于.Net平台常用的组件和框架整理
    Javascript中最常用的55个经典技巧(转)
  • 原文地址:https://www.cnblogs.com/cdyboke/p/6816220.html
Copyright © 2011-2022 走看看