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

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

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

功能分析

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

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

实现思路

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

完整代码

package main

import (
	"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控制台聊天室内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Go语言多人聊天室项目实战

    本文为大家分享了Go语言多人聊天室项目实战,供大家参考,具体内容如下 功能需求 实现单撩 实现群撩 实现用户上线的全网通知 实现用户昵称 实现聊天日志的存储和查看 服务端实现 type Client struct { conn net.Conn name string addr string } var ( //客户端信息,用昵称为键 //clientsMap = make(map[string]net.Conn) clientsMap = make(map[string]Client) ) f

  • 一百行Golang代码实现简单并发聊天室

    项目介绍:Golang100行代码实现高并发聊天室,其中实现的功能有:上下线广播,私聊,用户改名,超时强踢,在线用户检测等 在开始项目前,我们需要理解贯穿这整个项目的两个重要变量,若能理解这两个变量的使用,那么并发聊天室项目会变得手到擒来.第一个是onlinemap全局map,第二个是Message全局channel. 取名为onlinemap的全局map类型为map[string][client],这个全局字典是用来存储当前在此聊天室的用户的,key值是string类型,为用户的ip地址+Po

  • golang基于websocket实现的简易聊天室程序

    本文实例讲述了golang基于websocket实现的简易聊天室.分享给大家供大家参考,具体如下: 先说点无关的,最近忙于工作没有更新博客,今天休息顺便把golang websocket研究了一下,挺好玩的,写了一个聊天室,分享给大家. websocket包 : code.google.com/p/go.net/websocket 文档 : http://go.pkgdoc.org/code.google.com/p/go.net/websocket 首先安装websocket包 复制代码 代码

  • 利用GO语言实现多人聊天室实例教程

    前言 运用go里面的net包中的相关方法来实现一个基于tcp的简单多人聊天室,用一个服务器来管理,主要反馈客户端是否连接成功并显示客户端输入的内容,并且发送给每一个在服务器上连接的客服端,下面话不多说了,来一起看看详细的介绍吧. 示例代码 服务器代码 // server package main import ( "fmt" "net" ) var ConnMap map[string]*net.TCPConn func checkErr(err error) in

  • golang实现一个简单的websocket聊天室功能

    基本原理: 1.引入了 golang.org/x/net/websocket 包. 2.监听端口. 3.客户端连接时,发送结构体: {"type":"login","uid":"我是用户名","msg":"登陆成功"}' .服务端根据login信息,维护一个map,用来存放不同用户的连接体. 4.有用户发言时,将msg内容轮询发给给一个用户. 5.客户端使用js websocket功能,

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

    使用socket和channel,实现简单控制台聊天室 这里使用socket和channel,演示在GO中如何编写一个简单网络程序 功能分析 聊天室主要功能:用户可以加入/离开聊天室:每个用户发送的消息,广播给所有人 聊天室分为客户端和服务端,客户端负责发送消息和打印服务器消息,服务器负责接收客户端消息,并广播给所有人 客户端可以使用telnet程序 服务端是需要实现的.需要实现的功能, 如何保存多个客户端的连接,管理连接的接入与断开 如何接收和广播客户端消息 实现思路 通过功能分析,拆分为聊天

  • c#基于WinForm的Socket实现简单的聊天室 IM

    1:什么是Socket 所谓套接字(Socket),就是对网络中不同主机上的应用进程之间进行双向通信的端点的抽象. 一个套接字就是网络上进程通信的一端,提供了应用层进程利用网络协议交换数据的机制. 从所处的地位来讲,套接字上联应用进程,下联网络协议栈,是应用程序通过网络协议进行通信的接口,是应用程序与网络协议根进行交互的接口. 2:客服端和服务端的通信简单流程 3:服务端Code: using System; using System.Collections.Generic; using Sys

  • 玩转NODE.JS(四)-搭建简单的聊天室的代码

    Nodejs好久没有跟进了,最近想用它搞一个聊天室,然后便偶遇了socket.io这个东东,说是可以用它来简单的实现实时双向的基于事件的通讯机制.我便看了一些个教程使用它来搭建一个超级简单的聊天室. 初始化项目 在电脑里新建一个文件夹,叫做"chatroom",然后使用npm进行初始化: $ npm init 然后根据提示以及相关信息一步一步输入,当然也可以一路回车下去,之后会在项目里生成一个package.json文件,里面的信息如下: $ cat package.json { &q

  • Java基于UDP协议实现简单的聊天室程序

    最近比较闲,一直在抽空回顾一些Java方面的技术应用. 今天没什么事做,基于UDP协议,写了一个非常简单的聊天室程序. 现在的工作,很少用到socket,也算是对Java网络编程方面的一个简单回忆. 先看一下效果: 实现的效果可以说是非常非常简单,但还是可以简单的看到一个实现原理.  "聊天室001"的用户,小红和小绿相互聊了两句,"聊天室002"的小黑无人理会,在一旁寂寞着. 看一下代码实现: 1.首先是消息服务器的实现,功能很简单: •将客户端的信息(进入了哪一

  • Java实现简单局域网聊天室

    本文实例为大家分享了Java实现简单局域网聊天室的具体代码,供大家参考,具体内容如下 Java 的Socket编程: 1.TCP协议是面向连接的.可靠的.有序的.以字节流的方式发送数据,通过三次握手方式建立连接,形成传输数据的通道,在连接中进行大量数据的传输,效率会稍低 2.Java中基于TCP协议实现网络通信的类 客户端的Socket类 服务器端的ServerSocket类 3.Socket通信的步骤 ① 创建ServerSocket和Socket ② 打开连接到Socket的输入/输出流 ③

  • C语言实现简单的聊天室功能

    用C语言实现简单的聊天室功能,供大家参考,具体内容如下 服务器端 #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<winsock.h> #pragma comment(lib, "ws2_32.lib") #define L 256 int main() { char SendBuf[L]; char ReceiveBuf[L]; int SendLen; int ReceiveLen; in

  • ASP建立一个简单的聊天室

    经过一个阶段的asp学习,下面我们结合所学过的内容建立一个最简单的聊天室,虽然很简单,但是大家可以通过它来掌握一个聊天室建立的基本过程,并且可以不断的完善其功能. 下面介绍其主要步骤: 1,添加Global.asa文件里面的代码.这部分代码主要处理Application_onStart事件,在此事件中,定义了一个有15个元素的数据,并把它赋给了一个Application对象的属性.Global.asa文件的内容如下. <SCRIPT LANGUAGE="VBScript" RUN

  • Android编写简单的聊天室应用

    最近写了一个简单的聊天室应用,可以发送表情,更改头像这些功能.主要技术点就是怎样把表情图片放到textview等Ui控件中展示.这里废话不多说,下面是效果图: 这里主要讲下怎样把文本替换到表情,先说下思路,首先我们的图片是保存在本地资源目录drawable中而所有的资源文件都是R这个类来管理,所以我们可以利用正则表达式找出图片id包装成ImageSpan然后把ImageSpan放到SpannableString中,最后把SpannableString放入edittext中,下面是源码: pack

  • Node.js+express+socket实现在线实时多人聊天室

    本文实例为大家分享了Node.js+express+socket实现在线实时多人聊天室的具体代码,供大家参考,具体内容如下 文件结构如下: 前端部分: 登录页面Login部分: login.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="

  • Java实现简单的聊天室功能

    本文实例为大家分享了Java实现简单聊天室功能的具体代码,供大家参考,具体内容如下 一.客户端的创建 1.我们可以用Socket来创建客户端 /**   *@类名 Client   *@描述 TODO 客户端 1   *@版本 1.0   *@创建人 XuKang   *@创建时间 2020/9/24 16:18   **/ public class Client {     public static void main(String[] args) throws UnknownHostExc

随机推荐