本节将带领大家结合咱们前面所学的知识开发一个聊天的小程序,它可以在几个用户之间相互广播文本消息。这个程序里包含4个goroutine。主goroutine和广播(broadcaster)goroutine,每一个连接里面有一个连接处理(handleConn)goroutine和一个客户写入(clientwriter)goroutine。

广播器(broadcaster)是关于如何使用select的一个规范说明,因为它需要对三种不同的消息进行响应。

如下所示,主goroutine的工作是监听端口,接受连接客户端的网络连接。对每一个连接,它创建一个新的handleConngoroutine。

packagemainimport("bufio""fmt""log""net")funcmain(){listener,err:=net.Listen("tcp","localhost:8000")iferr!=nil{log.Fatal(err)}gobroadcaster()for{conn,err:=listener.Accept()iferr!=nil{log.Print(err)continue}gohandleConn(conn)}}

下一个是广播器,它使用局部变量clients来记录当前连接的客户集合。每个客户唯一被记录的信息是其对外发送消息通道的ID,下面是细节:

typeclientchan

广播者监听两个全局的通道entering和leaving,通过它们通知客户的到来和离开,如果它从其中一个接收到事件,它将更新clients集合。如果客户离开,那么它关闭对应客户对外发送消息的通道。

广播者也监听来自messages通道的事件,所有的客户都将消息发送到这个通道。当广播者接收到其中一个事件时,它把消息广播给所有客户。

现在来看一下每个客户自己的goroutine。handleConn函数创建一个对外发送消息的新通道,然后通过entering通道通知广播者新客户到来。

接着,它读取客户发来的每一行文本,通过全局接收消息通道将每一行发送给广播者,发送时在每条消息前面加上发送者ID作为前缀。一旦从客户端读取完毕消息,handleConn通过leaving通道通知客户离开,然后关闭连接。

funchandleConn(connnet.Conn){ch:=make(chanstring)//对外发送客户消息的通道goclientWriter(conn,ch)who:=conn.RemoteAddr().String()ch

另外,handleConn函数还为每一个客户创建了写入(clientwriter)goroutine,它接收消息,广播到客户的发送消息通道中,然后将它们写到客户的网络连接中。客户写入者的循环在广播者收到leaving通知并且关闭客户的发送消息通道后终止。

下面的信息展示了同一个机器上的一个服务器和两个客户端,它们使用netcat程序来聊天:

$gobuildgopl.io/ch8/main

$gobuildgopl.io/ch8/netcat

$./main&

$./netcat

Youare127.0.0.1:64208  $./netcat

127.0.0.1:64211hasarrivedYouare127.0.0.1:64211

Hi!

127.0.0.1:64208:Hi! 127.0.0.1:64208:Hi!

Hiyourself.

127.0.0.1:64211:Hiyourself. 127.0.0.1:64211:Hiyourself.

^C

127.0.0.1:64208hasleft

$./netcat

Youare127.0.0.1:64216 127.0.0.1:64216hasarrived

Welcome.

127.0.0.1:64211:Welcome.127.0.0.1:64211:Welcome.

^C

127.0.0.1:64211hasleft

netcat的完整代码如下所示:

//netcat.go//netcat是一个简单的TCP服务器读/写客户端packagemainimport("io""log""net""os")funcmain(){conn,err:=net.Dial("tcp","localhost:8000")iferr!=nil{log.Fatal(err)}done:=make(chanstruct{})gofunc(){io.Copy(os.Stdout,conn)//注意:忽略错误log.Println("done")done

当有n个客户session在连接的时候,程序并发运行着2n+2个相互通信的goroutine,它不需要隐式的加锁操作。clientsmap限制在广播器这一个goroutine中被访问,所以不会并发访问它。唯一被多个goroutine共享的变量是通道以及net.Conn的实例,它们又都是并发安全的。

go消息服务器吗,Go语言聊天服务器相关推荐

  1. lol好友列表显示聊天服务器断开,lol聊天服务器断开 英雄联盟聊天服务器连不上解决办法...

    亲们在玩英雄联盟的时候经常会遇到一个情况:右侧的LOL聊天服务器断开:尤其大家在跟朋友开黑的时候遇到这个情况无法拉好友加入游戏是非常恼火的,本文就聊天服务器连不上这个问题为大家详细解答,只需一分钟包教 ...

  2. 易语言服务器php,易语言PHP服务器源码

    易语言PHP服务器源码系统结构:监听服务,编码转换程序,进制转换,取页面地址,取域名,取端口,取指定内容中间,取文本之间,取文本之后,ChrW,十到十六,到十六进制文本,去除首部零,URL编码_UTF ...

  3. 易语言 html 服务器,更新易语言http服务器开发框架

    测试前后内存占用基本不变,错误增量几乎为0 .如果真 (启动ipv4tcp服务器 ("0.0.0.0", 80, 128, 1000, 线程比, erro) = 假) .如果 (是 ...

  4. 通过python 构建一个简单的聊天服务器

    构建一个 Python 聊天服务器 一个简单的聊天服务器 现在您已经了解了 Python 中基本的网络 API:接下来可以在一个简单的应用程序中应用这些知识了.在本节中,将构建一个简单的聊天服务器.使 ...

  5. 局域网服务器发送消息,Java实现简单局域网聊天室

    本文实例为大家分享了Java实现简单局域网聊天室的具体代码,供大家参考,具体内容如下 Java 的Socket编程: 1.TCP协议是面向连接的.可靠的.有序的.以字节流的方式发送数据,通过三次握手方 ...

  6. 服务器收到消息加入数组,从聊天服务器发送到聊天客户端的数组更新

    我发现了一个聊天服务器的代码,我有一个简短的问题.这是关于以下摘录:从聊天服务器发送到聊天客户端的数组更新 clientOutputStreams.add(作家); 显然,这种字符串数组应该被发送到聊 ...

  7. 深入浅出Node.js游戏服务器开发--分布式聊天服务器搭建

    From: http://www.infoq.com/cn/articles/game-server-development-2?utm_source=infoq&utm_medium=rel ...

  8. 400-集群聊天服务器的客户端开发

    我们之前把聊天服务器的代码基本上功能开发完了,在后面转成集群版本的时候要引入中间件-基于发布订阅的Redis. 现在我们先开始客户端的开发 我们聊天服务器项目工程的客户端和服务器会共用很多代码,所以把 ...

  9. 集群聊天服务器项目(四)——项目总结

    集群聊天服务器项目总结 首先是就是项目介绍集群聊天服务器项目(零)--项目介绍中的内容,就不再次copy过来了 项目简单介绍 技术栈 环境和库依赖 按模块介绍整个项目 程序的主要模块是网络模块.业务模 ...

最新文章

  1. MySQL之concat、concat_ws以及group_concat的使用
  2. python开源聊天机器人ChatterBot——聊天机器人搭建、流程分析、源码分析
  3. PicGo五分钟打造你的私人图床(稳定、快速、免费)
  4. Python中from import和import的区别?没有比这更好的回答了
  5. 用python简单处理图片(4):图像中的像素访问
  6. 链接服务器 '(null)' 的 OLE DB 访问接口'STREAM' 返回了对列 '[!BulkInsert].field' 无效的数据...
  7. “会”和 好”纯粹是两个概念
  8. MySQL数据库的数据类型decimal详解
  9. 更安全的Web通信HTTPS
  10. C#:winform使用chart控件绘制折线图,时间轴可缩放
  11. 波兰表达式(前序表达式)的计算(栈)
  12. mysql setautocommit_MySql 中的setAutoCommit方法
  13. 解决Hbuliderx的代码不能自动补全的问题
  14. 记一次YUV图像分析(二)
  15. 再多的非标电气设计也不怕了
  16. Robot Framework+Autoit 安装教程
  17. 广州大学校园网路由器傻瓜式自助刷机教程
  18. 直播弹幕系统(三)- 直播在线人数统计
  19. “缺钱”的女人,掩饰不住以下三个特征,别不信
  20. 苹果网页显示无法连接服务器失败怎么办啊,苹果手机自带的浏览器显示无法连接互联网是怎么回事啊...

热门文章

  1. 机器学习笔记:岭回归(L2正则化)
  2. 数据库笔记——数据模型
  3. R语言实战应用精讲50篇(十四)-R语言构建层次分析模型
  4. Python 知识点全解析系列之列表推导式(list comprehension)
  5. 深度学习核心技术精讲100篇(二十一)-深入理解Dirichlet分布及过程
  6. java 访问 网络swf_JAVA访问网络资源
  7. Python编程基础:第三十五节 文件删除Delete a File
  8. 如何基于Redis Replication设计并实现Redis-replicator?
  9. 在线支付之风控系统架构选型
  10. mysql @变量和变量的区别及怎么判断记录唯一性