GO使用socket和channel实现简单控制台聊天室

收集整理的这篇文章主要介绍了GO使用socket和channel实现简单控制台聊天室,觉得挺不错的,现在分享给大家,也给大家做个参考。

使用socket和channel,实现简单控制台聊天室

这里使用socket和channel,演示在GO中如何编写一个简单网络程序

功能分析

聊天室主要功能:用户可以加入/离开聊天室;每个用户发送的消息,广播给所有人
聊天室分为客户端和服务端,客户端负责发送消息和打印服务器消息,服务器负责接收客户端消息,并广播给所有人
客户端可以使用telnet程序
服务端是需要实现的。需要实现的功能,

  1. 如何保存多个客户端的连接,管理连接的接入与断开
  2. 如何接收和广播客户端消息

实现思路

通过功能分析,拆分为聊天室结构体和客户端结构体
聊天室结构体负责管理当前接入的客户端和广播消息
客户端结构体负责管理socket连接和需要接收与发送的数据
客户端连接/断开时通知聊天室;客户端发送的消息实际是转发给聊天室,然后聊天室再广播出去

完整代码

package mainimport (	"bufio"	"fmt"	"LOG"	"net")tyPE Client struct {
	id      string	conn    *net.Conn	message chan string}
type Hub struct {
	clients  map[*Client]bool	entering chan *Client	leaving  chan *Client	messages chan string}
func main() {
    	hub := &
Hub{
		clients:  make(map[*Client]bool),		entering: make(chan *Client),		leaving:  make(chan *Client),		messages: make(chan string),	}
	listener, err := net.Listen("tcp", ":8000")	if err != nil {
		log.Fatal(err)	}
	go hub.broadcaster()	for {
		conn, err := listener.Accept()		if err != nil {
			log.PRintln(err)			continue		}
		go hub.handleConn(conn)	}
}
func (hub *Hub) broadcaster() {
	for {
		select {
    		case msg := <
-hub.messages:			for cli := range hub.clients {
    				cli.message <
- msg			}
    		case cli := <
    -hub.entering:			hub.clients[cli] = true		case cli := <
-hub.leaving:			delete(hub.clients, cli)		}
	}
}
func (hub *Hub) handleConn(conn net.Conn) {
    	defer conn.Close()	ch := make(chan string)	who := conn.RemoteAddr().String()	client := &
Client{
    who, &
conn, ch}
    	go hub.wrITeLoop(client)	ch <
    - "welcome " + client.id	hub.messages <
    - client.id + " join chat"	hub.entering <
    - client	hub.readLoop(client)	hub.messages <
    - client.id + " has left"	hub.leaving <
- client}
func (hub *Hub) writeLoop(client *Client) {
	for msg := range client.message {
		fmt.fprintf(*client.conn, "%s\n", msg)	}
}
func (hub *Hub) readLoop(client *Client) {
	input := bufio.NewScanner(*client.conn)	for input.Scan() {
    		hub.messages <
- client.id + ": " + input.Text()	}
}
    

分析

实现的关键是封装了客户端通信channel,无论是远程发送过来的消息还是聊天室广播的消息,都通过这个channel传递,且这个channel是绑定客户端的
参考链接中,直接使用channel来定义客户端type client chan< - string,其实更能表达这一点
为了容易理解,这里将channel封装为客户端的一个通信管道,客户端还可以有别的属性,例如:id、连接和超时时间等

参考: Go 网络编程示例

到此这篇关于GO实现简单控制台聊天室的文章就介绍到这了,更多相关go控制台聊天室内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!

您可能感兴趣的文章:

  • Golang实现Directional Channel(定向通道)
  • Go语言七篇入门教程四通道及Goroutine
  • Go语言带缓冲的通道实现
  • Golang 并发以及通道的使用方式
  • Golang通道的无阻塞读写的方法示例
  • 深入理解Golang Channel 的底层结构
  • Go语言中的通道channel详情