go简单聊天室的搭建

Go语言实践_实现一(服务器端)对多(客户端)在线聊天室

一、 目的

运用Go语言中的goroutine和通道实现一个简单的一个服务器端对多个客户端的在线聊天

二、设计思路

与一对一的设计思路类似,就是加了个线程的操作。

1,服务器端声明一个map,并打开监听端口;

2,客户端打开监听端口,同时连入服务器端;

3,在客户端上给自己起一个昵称,并输出,同时启动一个线程;

4,服务器端接收一个昵称,并存入map;

5,声明一个空的字符串,并写入要群发的消息;

6,服务器端解析发送的消息(msg_str[0]的值):

nick:使该客户端加入聊天室并广播连上服务器端的所有其他客户端;
say:广播客户端发出的消息;
quit:使该客户端退出,断开与服务器端的连接,并将退出消息广播给其他连上服务器端的所有其他客户端;

三、代码

server.go

// one sever to more client chat room
//This is chat sever
package main

import (
    "fmt"
    "net"
    "strings"
)

var ConnMap map[string]net.Conn = make(map[string]net.Conn)  //声明一个集合

//ConnMap := make(map[string]net.Conn)

func main() {
    listen_socket, err := net.Listen("tcp", "127.0.0.1:8000")  //打开监听接口
    if err != nil {
        fmt.Println("server start error")
    }

    defer listen_socket.Close()
    fmt.Println("server is wating ....")

    for {
        conn, err := listen_socket.Accept()  //收到来自客户端发来的消息
        if err != nil {
            fmt.Println("conn fail ...")
        }
        fmt.Println(conn.RemoteAddr(), "connect successed")

        go handle(conn)  //创建线程
    }
}

func handle(conn net.Conn) {
    for {
        data := make([]byte, 255)  //创建字节流 (此处同 一对一 通信)
        msg_read, err := conn.Read(data)  //声明并将从客户端读取的消息赋给msg_read 和err
        if msg_read == 0 || err != nil {
            continue
        }

        //解析协议
        msg_str := strings.Split(string(data[0:msg_read]), "|")  //将从客户端收到的字节流分段保存到msg_str这个数组中

        switch msg_str[0] {
        case "nick":  //加入聊天室
            fmt.Println(conn.RemoteAddr(), "-->", msg_str[1])  //nick占在数组下标0上,客户端上写的昵称占在数组下标1上
            for k, v := range ConnMap {  //遍历集合中存储的客户端消息
                if k != msg_str[1] {
                    v.Write([]byte("[" + msg_str[1] + "]: join..."))
                }
            }
            ConnMap[msg_str[1]] = conn
        case "say":   //转发消息
            for k, v := range ConnMap {  //k指客户端昵称   v指客户端连接服务器端后的地址
                if k != msg_str[1] {  //判断是不是给自己发,如果不是
                    fmt.Println("Send "+msg_str[2]+" to ", k)  //服务器端将消息转发给集合中的每一个客户端
                    v.Write([]byte("[" + msg_str[1] + "]: " + msg_str[2]))  //给除了自己的每一个客户端发送自己之前要发送的消息
                }
            }
        case "quit":  //退出
            for k, v := range ConnMap {  //遍历集合中的客户端昵称
                if k != msg_str[1] {  //如果昵称不是自己
                    v.Write([]byte("[" + msg_str[1] + "]: quit"))  //给除了自己的其他客户端昵称发送退出的消息,并使Write方法阻塞
                }
            }
            delete(ConnMap, msg_str[1])  //退出聊天室
        }
    }
}

client.go

// one sever to more client chat room
//This is chat client
package main

import (
	"fmt"
	"net"
)

var nick string = "" //声明聊天室的昵称

func main() {
	conn, err := net.Dial("tcp", "127.0.0.1:8000") //打开监听端口
	if err != nil {
		fmt.Println("conn fail...")
	}
	defer conn.Close()
	fmt.Println("client connect server successed \n")

	//给自己取一个聊天室的昵称
	fmt.Printf("Make a nickname:")
	fmt.Scanf("%s", &nick)             //输入昵称
	fmt.Println("hello : ", nick)      //客户端输出
	conn.Write([]byte("nick|" + nick)) //将信息发送给服务器端

	go Handle(conn) //创建线程

	var msg string
	for {
		msg = ""                                      //声明一个空的消息
		fmt.Scan(&msg)                                //输入消息
		conn.Write([]byte("say|" + nick + "|" + msg)) //三段字节流 say | 昵称 | 发送的消息
		if msg == "quit" {                            //如果消息为quit
			conn.Write([]byte("quit|" + nick)) //将quit字节流发送给服务器端
			break                              //程序结束运行
		}
	}
}

func Handle(conn net.Conn) {

	for {

		data := make([]byte, 255)        //创建一个字节流
		msg_read, err := conn.Read(data) //将读取的字节流赋值给msg_read和err
		if msg_read == 0 || err != nil { //如果字节流为0或者有错误
			break
		}

		fmt.Println(string(data[0:msg_read])) //把字节流转换成字符串
	}
}

编译运行服务端与客户端

go run server.go
go run client.go

运行结果展示
运行结果

转载自Go语言实践_实现一(服务器端)对多(客户端)在线聊天室
作者:Zoctopus_Zhang
出处:http://www.cnblogs.com/OctoptusLian/

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Centrifugo 是一个用 Golang 实现的基于 Websocket 或者 SockJS 的实时通信平台。支持数千个同时连接,提供基于频道的出版/订阅模式。PUB/SUB容易和现有系统集成– 不改变已有后端情况下为系统提供实时通信能力。HTTP API 和已有后端通信 . API clients for Python, Ruby, PHP, Go, NodeJS.浏览器可以通过SockJS或者纯粹Websocket协议和centrifugal通信. 提供 iOS和Android平台SDK采用Redis实现分布式部署.SHA-256 HMAC连接认证和隐私保护多种类型的频道 – 私有, 用户限制,客户端限制通过名字空间灵活配置频道支持即时消息和历史消息支持用户加入/离开消息网络重连后可以恢复消息内置管理界面,提供多种计量(Metrics)可用于WebRTC信令服务器多种部署手段(docker 镜像, RPM/DEB 包, Nginx 配置, TLS certificates)MIT license通讯模型:Centrifugo 包含如下子项目:centrifugo - 采用 Go 语言开发的实时消息传递服务器centrifuge-js - Javascript 客户端,可直接在浏览器使用centrifuge-android - Android 的客户端开发包,可通过 WebSockets 与服务器通讯centrifuge-ios - Swift 开发包centrifuge-go - Go 客户端开发包cent - Python 开发包adjacent - Cent 的小型封装包,简化了与 Django 框架的集成rubycent - Ruby gem to communicate  with Centrifugo server API.phpcent - PHP client to communicate  with Centrifugo server API.gocent - Go client to communicate  with Centrifugo server API.jscent - NodeJS client to communicate  with Centrifugo server API.web - Centrifugo 的管理界面,基于 ReactJS 开发 标签:Centrifugo

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值