热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

go随websocket存亡的token

1packagetoken23import(4cryptomd55fmt6io7mathrand8sync9time10)1112typeUserstruc
技术分享技术分享
 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  {
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也结束了生命周期

go 随websocket存亡的token


推荐阅读
  • importpymysql#一、直接连接mysql数据库'''coonpymysql.connect(host'192.168.*.*',u ... [详细]
  • 在多线程并发环境中,普通变量的操作往往是线程不安全的。本文通过一个简单的例子,展示了如何使用 AtomicInteger 类及其核心的 CAS 无锁算法来保证线程安全。 ... [详细]
  • 原文网址:https:www.cnblogs.comysoceanp7476379.html目录1、AOP什么?2、需求3、解决办法1:使用静态代理4 ... [详细]
  • 文章目录Golang定时器Timer和Tickertime.Timertime.NewTimer()实例time.AfterFunctime.Tickertime.NewTicke ... [详细]
  • 命令模式是一种行为设计模式,它将请求封装成一个独立的对象,从而允许你参数化不同的请求、队列请求或者记录请求日志。本文将详细介绍命令模式的基本概念、组件及其在实际场景中的应用。 ... [详细]
  • Spark中使用map或flatMap将DataSet[A]转换为DataSet[B]时Schema变为Binary的问题及解决方案
    本文探讨了在使用Spark的map或flatMap算子将一个数据集转换为另一个数据集时,遇到的Schema变为Binary的问题,并提供了详细的解决方案。 ... [详细]
  • 第二十五天接口、多态
    1.java是面向对象的语言。设计模式:接口接口类是从java里衍生出来的,不是python原生支持的主要用于继承里多继承抽象类是python原生支持的主要用于继承里的单继承但是接 ... [详细]
  • 本项目通过Python编程实现了一个简单的汇率转换器v1.02。主要内容包括:1. Python的基本语法元素:(1)缩进:用于表示代码的层次结构,是Python中定义程序框架的唯一方式;(2)注释:提供开发者说明信息,不参与实际运行,通常每个代码块添加一个注释;(3)常量和变量:用于存储和操作数据,是程序执行过程中的重要组成部分。此外,项目还涉及了函数定义、用户输入处理和异常捕获等高级特性,以确保程序的健壮性和易用性。 ... [详细]
  • DVWA学习笔记系列:深入理解CSRF攻击机制
    DVWA学习笔记系列:深入理解CSRF攻击机制 ... [详细]
  • 深入解析:Synchronized 关键字在 Java 中对 int 和 Integer 对象的作用与影响
    深入探讨了 `Synchronized` 关键字在 Java 中对 `int` 和 `Integer` 对象的影响。尽管初看此题似乎简单,但其实质在于理解对象的概念。根据《Java编程思想》第二章的观点,一切皆为对象。本文详细分析了 `Synchronized` 关键字在不同数据类型上的作用机制,特别是对基本数据类型 `int` 和包装类 `Integer` 的区别处理,帮助读者深入理解 Java 中的同步机制及其在多线程环境中的应用。 ... [详细]
  • 全面解析JavaScript代码注释技巧与标准规范
    在Web前端开发中,JavaScript代码的可读性和维护性至关重要。本文将详细介绍如何有效地使用注释来提高代码的可读性,并探讨JavaScript代码注释的最佳实践和标准规范。通过合理的注释,开发者可以更好地理解和维护复杂的代码逻辑,提升团队协作效率。 ... [详细]
  • 本文汇集了我在网络上搜集以及在实际面试中遇到的前端开发面试题目,并附有详细解答。无论是初学者还是有一定经验的开发者,都应深入理解这些问题背后的原理,通过系统学习和透彻研究,逐步形成自己的知识体系和技术框架。 ... [详细]
  • 在 CentOS 7 系统中安装 Scrapy 时遇到了一些挑战。尽管 Scrapy 在 Ubuntu 上安装简便,但在 CentOS 7 上需要额外的配置和步骤。本文总结了常见问题及其解决方案,帮助用户顺利安装并使用 Scrapy 进行网络爬虫开发。 ... [详细]
  • 在处理 XML 数据时,如果需要解析 `` 标签的内容,可以采用 Pull 解析方法。Pull 解析是一种高效的 XML 解析方式,适用于流式数据处理。具体实现中,可以通过 Java 的 `XmlPullParser` 或其他类似的库来逐步读取和解析 XML 文档中的 `` 元素。这样不仅能够提高解析效率,还能减少内存占用。本文将详细介绍如何使用 Pull 解析方法来提取 `` 标签的内容,并提供一个示例代码,帮助开发者快速解决问题。 ... [详细]
  • 本文详细解析了微信服务端示例类的功能与应用。其中,`ClientResponseHandler` 类主要用于处理微信支付所需的响应数据,而 `TenpayHttpClient` 则是对 HTTP 请求(包括 GET 和 POST 方法)进行了封装,以便在内部调用时更加便捷和高效。这些工具类在实际开发中起到了关键作用,开发者无需深入了解其底层实现细节,即可轻松集成微信支付功能。 ... [详细]
author-avatar
点提土八撇又254
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有