IMV3.0
经历了两个版本,基础内容在前面,可以使用之前的基础环境:
v1:
https://blog.csdn.net/wtt234/article/details/132139454v2:
https://blog.csdn.net/wtt234/article/details/132144907
一、代码组织结构
二、代码
2.1user.go
package mainimport "net"type User struct {Name stringAddr stringC chan stringconn net.Connserver *Server
}//创建一个用户的API
func NewUser(conn net.Conn, server *Server) *User {userAddr := conn.RemoteAddr().String()user := &User{Name: userAddr,Addr: userAddr,C: make(chan string),conn: conn,server: server,}//启动监听当前user channel消息的goroutinego user.ListenMessage()return user
}//用户的上线业务
func (this *User) Online() {//用户上线,将用户加入到onlineMap中this.server.mapLock.Lock()this.server.OnlineMap[this.Name] = thisthis.server.mapLock.Unlock()//广播当前用户上线消息this.server.BroadCast(this, "已上线")
}//用户的下线业务
func (this *User) Offline() {//用户下线,将用户从onlineMap中删除this.server.mapLock.Lock()delete(this.server.OnlineMap, this.Name)this.server.mapLock.Unlock()//广播当前用户上线消息this.server.BroadCast(this, "下线")}//用户处理消息的业务
func (this *User) DoMessage(msg string) {this.server.BroadCast(this, msg)
}//监听当前User channel的 方法,一旦有消息,就直接发送给对端客户端
func (this *User) ListenMessage() {for {msg := <-this.Cthis.conn.Write([]byte(msg + "\n"))}
}
2.2server.go
package mainimport ("fmt""io""net""sync"
)type Server struct {Ip stringPort int//在线用户的列表OnlineMap map[string]*UsermapLock sync.RWMutex//消息广播的channelMessage chan string
}//创建一个server的接口
func NewServer(ip string, port int) *Server {server := &Server{Ip: ip,Port: port,OnlineMap: make(map[string]*User),Message: make(chan string),}return server
}//监听Message广播消息channel的goroutine,一旦有消息就发送给全部的在线User
func (this *Server) ListenMessager() {for {msg := <-this.Message//将msg发送给全部的在线Userthis.mapLock.Lock()for _, cli := range this.OnlineMap {cli.C <- msg}this.mapLock.Unlock()}
}//广播消息的方法
func (this *Server) BroadCast(user *User, msg string) {sendMsg := "[" + user.Addr + "]" + user.Name + ":" + msgthis.Message <- sendMsg
}func (this *Server) Handler(conn net.Conn) {//...当前链接的业务//fmt.Println("链接建立成功")user := NewUser(conn, this)user.Online()//接受客户端发送的消息go func() {buf := make([]byte, 4096)for {n, err := conn.Read(buf)if n == 0 {user.Offline()return}if err != nil && err != io.EOF {fmt.Println("Conn Read err:", err)return}//提取用户的消息(去除'\n')msg := string(buf[:n-1])//用户针对msg进行消息处理user.DoMessage(msg)}}()//当前handler阻塞select {}
}//启动服务器的接口
func (this *Server) Start() {//socket listenlistener, err := net.Listen("tcp", fmt.Sprintf("%s:%d", this.Ip, this.Port))if err != nil {fmt.Println("net.Listen err:", err)return}//close listen socketdefer listener.Close()//启动监听Message的goroutinego this.ListenMessager()for {//acceptconn, err := listener.Accept()if err != nil {fmt.Println("listener accept err:", err)continue}//do handlergo this.Handler(conn)}
}
2.3main.go
package mainfunc main() {server := NewServer("127.0.0.1", 8000)server.Start()
}
三、客户端登录测试
客户端1登录
客户端2登录发送信息
相关文章:

IMV3.0
经历了两个版本,基础内容在前面,可以使用之前的基础环境: v1: https://blog.csdn.net/wtt234/article/details/132139454 v2: https://blog.csdn.net/wtt234/article/details/132144907 一、代码组织结构 二、代码 2.…...

怎么在树莓派环境上搭建web网站,并发布到外网可访问,今天教给大家
怎么在树莓派上搭建web网站,并发布到外网可访问? 文章目录 怎么在树莓派上搭建web网站,并发布到外网可访问?概述使用 Raspberry Pi Imager 安装 Raspberry Pi OS测试 web 站点安装静态样例站点 将web站点发布到公网安装 Cpolarcpo…...

大文件传输软件| 生命科学中的关键因素
在2023年,生命科学领域以及其先进的科学技术吸引了人们的目光。这些研究背后,很少有人知道的是,其中涉及了大量的研究数据需要实时进行文件传输,以便于研究,合作,分享,分析,临床试验…...

varint编码实现原理
简言 1. varint即 variable int,也就是变长整型,在mysql,levelDB,protobuf中都有使用 2. varint编码的优点是对数值较小的数进行编码后占用字节较少,比如[0-127]只占用1个字节,[128~16383]只占用2个字节。…...

如果新电脑是刚安装的mysql,但是旧电脑迁移过来的文件里面有相关的rails文件,运行rake db:migrate一直报错
$ bundle exec rake db:migrate#运行完命令报错 rake aborted! LoadError: libmysqlclient.so.21: cannot open shared object file: No such file or directory - /home/meiyi/.asdf/installs/ruby/2.6.9/lib/ruby/gems/2.6.0/gems/mysql2-0.5.5/lib/mysql2/mysql2.so /home/m…...

ChatGPT已闯入学术界,Elsevier推出AI工具
2022年11月,OpenAI公司发布了ChatGPT,这是迄今为止人工智能在现实世界中最重要的应用之一。 当前,互联网搜索引擎中出现了越来越多的人工智能(AI)聊天机器人,例如谷歌的Bard和微软的Bing,看起来…...

深度学习论文: RepViT: Revisiting Mobile CNN From ViT Perspective及其PyTorch实现
深度学习论文: RepViT: Revisiting Mobile CNN From ViT Perspective及其PyTorch实现 RepViT: Revisiting Mobile CNN From ViT Perspective PDF: https://arxiv.org/pdf/2307.09283.pdf PyTorch代码: https://github.com/shanglianlm0525/CvPytorch PyTorch代码: https://gith…...

R语言3_安装SeurateData
环境Ubuntu22/20, R4.1 在命令行中键入, apt-get update apt install libcurl4-openssl-dev libssl-dev libxml2-dev libcairo2-dev libgtk-3-dev # libcairo2-dev :: systemfonts # libgtk :: textshaping进入r语言交互环境,键入, instal…...

详解Gillespie算法:使用Python构建分子化学模拟及其在随机多智能体动力学中的应用
第一部分:Gillespie算法简介 Gillespie算法是一种利用蒙特卡洛抽样模拟化学体系随机动力学行为的方法[3]。它是由Joseph L. Doob提出的,用于生成具有已知反应速率的随机方程组的统计上正确的轨迹(可能的解)[5]。在本文中,我们将详细介绍Gillespie算法的原理,并使用Pytho…...

Unity数字可视化学校_昼夜(三)
1、删除不需要的 UI using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI;public class EnvControl : MonoBehaviour {//UIprivate Button btnTime;private Text txtTime; //材质public List<Material> matListnew Li…...

使用罗技鼠标后 弹出当前页面的脚本发生错误AppData/Local/Temp/LogiUI/Pak/js/jquery-1.3.2.min.js解决
使用的台式机,没有蓝牙驱动,在用logi无线鼠标时,把鼠标连接插入台式机后弹出的如上图所示这个提示,无论是点是/否,还是X掉上图提示,电脑右下角的图依然存在。不习惯这丫的存在。 我重启还是有,然…...

Kubernetes(K8s)从入门到精通系列之十四:安装工具
Kubernetes K8s从入门到精通系列之十四:安装工具 一、kubectl二、kind三、minikube四、kubeadm 一、kubectl Kubernetes 命令行工具 kubectl, 让你可以对 Kubernetes 集群运行命令。 你可以使用 kubectl 来部署应用、监测和管理集群资源以及查看日志。 …...

【Python】Python元组学习
Python之元组学习记录 一、元组的特点 可以容纳多个数据可以容纳不同类型的数据(混装)数据是有序存储的(下标索引)允许重复数据存在不可以修改(增加或删除元素等)但内部list元素可以被修改支持while&…...

HTML 元素的属性有哪些?
聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ class⭐ id⭐ style⭐ src⭐ href⭐ alt⭐ width和height⭐ disabled⭐ value⭐ required⭐ placeholder⭐ checked⭐ selected⭐ target⭐ colspan和rowspan⭐ 写在最后 ⭐ 专栏简介 前端入门之旅:探索Web开发的奇妙世界 记得…...

Spring之事务实现方式及原理
目录 Spring事务简介 Spring支持事务管理的两种方式 编程式事务控制 声明式事务管理 Spring事务角色 未开启事务之前 开启Spring的事务管理后 事务配置 事务传播行为 事务传播行为的可选值 Spring事务简介 事务作用:在数据层保障一系列的数据库操作同成功…...

为独立服务器增加安全性的简单步骤
为独立服务器增加安全性的简单步骤 马上注册成为ROSABC会员,随时发帖回复。 您需要 登录 才可以下载或查看,没有账号?会员注册 x 独立服务器是您业务的中心,它需要尽可能的安全。对企业中心的攻击可能会导致您失去知识产权&…...

JavaScript--Cookie
什么是 Cookie? 在JavaScript中,cookie是一种小型的文本文件,它存储在用户的计算机上。通过使用cookie,网站可以向用户的浏览器发送数据,并将该数据保留在浏览器中,使网站能够在不同页面之间传递数据或存储…...

【单片机】晨启科技,酷黑版,简易电压采集装置
简易电压采集装置(限MSP430、STM32单片机) 任务要求: 设计制作一个简易电压采集与显示装置,实现如下基本功能: 评分细则: 1.通过单片机内部ADC模块采集1路电压并通过OLED屏显示电压大小;&#x…...

任务12、Quality指令加持,Midjourney生成电影级数码作品
12.1 任务概述 本次实验任务旨在帮助你掌握Midjourney AI绘画中的Quality指令。通过深入介绍Quality指令的概念和作用,我们将解释为什么它在绘画中至关重要。通过测试不同的Quality参数对绘画效果的影响,并提供实战演示,你将学会如何在Midjourney中设置Quality参数以达到更…...

第4章 字符串和格式化输入/输出
本章介绍以下内容: 函数:strlen() 关键字:const 字符串 如何创建、存储字符串 如何使用strlen()函数获取字符串的长度 用C预处理器指令#define和ANSIC的const修饰符创建符号常量 本章重点介绍输入和输出。与程序交互和使用字符串可以编写个性…...

嵌入式开发学习(STC51-7-矩阵按键)
内容 按下S1-S16键,对应数码管最左边显示0-F 矩阵按键简介 独立按键与单片机连接时,每一个按键都需要单片机的一个I/O 口,若某单片机系统需较多按键,如果用独立按键便会占用过多的I/O口资源;而单片机 系统中I/O口资…...

WMS仓储管理系统的价值从哪些方面体现
仓库管理在不断改善,采用信息化来管理仓库。自从使用了WMS仓储管理系统解决方案后,仓库管理的效率大大提高了,而且WMS系统有很多价值。 首先,WMS系统可以帮助员工更省时省力地完成仓库管理工作,提高效率和准确性。传统…...

网站推荐第二期-沉浸式网页翻译
通过在浏览器上安装插件形式实现,接入多方翻译接口,实现全平台翻译功能,甚至可以使用openai的chatgpt,效率倍增。 不仅可以双语阅读网页,甚至pdf也支持翻译。 推荐网址如下: 双语网页翻译 - 电子书翻译 …...

【独立后台】快递小程序便宜寄快递系统小程序 对接易达
快递代发项目简介: 顾名思义就是帮发快递。原本产业链是客户-快递之间的联系,现在变成了客户-我们-快递,简单来说就是我们把客户聚集到一起团购到了更优惠的价格。很简单就是赚一个差价, 单子多就能和各个快递合作的平台&#x…...

【JVM】垃圾回收 ——自问自答2
Q: System.gc() 的理解 System.gc()底层调用的是 Runtime.getRuntime.gc(),会现实出发FullGC。 但是,它的调用附带一个免责声明,无法保证对垃圾收集器的调用。 Q: 内存溢出和内存泄漏? 内存溢出: 简而言之…...

MySQL数据库数据类型
MySQL数据库数据类型分类 在MySQL数据库中,MySQL数据类型分有四大类:数值类型、文本/二进制类型、时间日期和String类型。以下是这四大类的具体类型: 数值类型 数值类型的范围和字节大小: tinyint类型 tinyint类型只有一个字节…...

【力扣】27. 移除元素 <快慢指针、首尾指针>
【力扣】27. 移除元素 给你一个数组 nums 和一个值 val,你需要原地移除所有数值等于 val 的元素,并返回移除后数组的新长度。不要使用额外的数组空间,必须仅使用 O(1) 额外空间并原地修改输入数组。元素的顺序可以改变。你不需要考虑数组中超…...

【每日一题】—— C. Challenging Cliffs(Codeforces Round 726 (Div. 2))
🌏博客主页:PH_modest的博客主页 🚩当前专栏:每日一题 💌其他专栏: 🔴 每日反刍 🟡 C跬步积累 🟢 C语言跬步积累 🌈座右铭:广积粮,缓称…...
想在金融界拥有一席之地吗—社科院杜兰大学金融管理硕士助你圆梦
追求高学历是为了什么?一纸证书吗?显然并非如此,只有读过研的人才有话语权。在上升一个平台后,你必然会发现,更高学历得到的不止是一张文凭。而是更大的平台、更广阔的视野、更包容的环境,更多样的文化。最…...

Moonbeam与Nodle网络集成,增添物联网功能
领先的波卡跨链互连开发平台Moonbeam近期宣布与Nodle Network达成XCM集成,将NODL Token带到Moonbeam生态之中。本次集成将会开启波卡中Moonbeam和Nodle网络以及通过Moonbeam互连合约相连的远程链之间的流动性。 Nodle网络是一个为物联网(Internet of Th…...