zoukankan      html  css  js  c++  java
  • go实现多聊天并发 服务端

    package main

    import (
    "fmt"
    "net"
    "time"
    )
    type Client struct {
    ch chan string //用户发送数据的管道
    name string //用户名
    addr string//网络地址
    }
    var message = make(chan string) //用来保存用户的消息
    //定义一个map 值为在线的用户
    var onlineClientMap map[string]Client//
    func main() {
    listener,err := net.Listen("tcp","127.0.0.1:8000")
    if err !=nil{
    fmt.Println(err)
    }
    defer listener.Close()
    go Manager()
    //主协程,循环阻塞用户连接
    for{
    conn, err := listener.Accept()
    if err!=nil{
    fmt.Println(err)
    continue
    }
    go handleConn(conn)

    }

    }
    func makeMsg(client Client,msg string)(buff string){

    buff ="["+client.addr+"]"+client.name+":"+msg+" "
    return
    }

    func handleConn(conn net.Conn){
    cliAddr:= conn.RemoteAddr().String()
    defer conn.Close()
    client :=Client{
    make(chan string),
    cliAddr,
    cliAddr,
    }
    onlineClientMap[cliAddr] = client
    //给当前客户端发送信息
    go writeMsgToClient(client,conn)
    //广播某个在线
    message<-"I am here "
    message<- makeMsg(client,"login")
    //是否主动退出
    isQuit:=make(chan bool)
    hasData:= make(chan bool)
    //新开一个协程接收用户发过来的数据
    go func() {
    buff:= make([]byte,2048)
    for{
    n,err :=conn.Read(buff)
    fmt.Println(n)
    if err!=nil{
    fmt.Println(nil)
    }
    if n==0{
    fmt.Println("断开连接")
    isQuit<-true
    return
    }
    msg := string(buff[:n-1])
    if len(msg)==3&& msg =="who"{
    for _,tmp := range onlineClientMap{
    msg = tmp.addr+":"+tmp.name+" "
    conn.Write([]byte(msg))

    }
    }else{
    message<-makeMsg(client,msg)
    }
    hasData<-true
    }
    }()
    for{
    select {

    case <-isQuit:
    delete(onlineClientMap,cliAddr)//当前用户从map移除
    message<-makeMsg(client,"login out")//广播退出
    return
    case <-hasData:

    case <-time.After(60*time.Second):
    delete(onlineClientMap,cliAddr)//当前用户从map移除
    message<-makeMsg(client,"time out")//广播退出
    return
    }



    }

    }
    func Manager() {
    onlineClientMap = make(map[string]Client)//给map分配空间
    for{
    msg := <-message
    for _ ,client :=range onlineClientMap{
    client.ch<-msg

    }
    }
    }

    func writeMsgToClient(client Client,conn net.Conn) {
    for msg:= range client.ch{
    conn.Write([]byte(msg))
    }

    }
  • 相关阅读:
    “北漂”的那些年 5
    “北漂”的那些年 4
    全国省市区代码-2020版
    记一次CDH修改IP
    Python爬取抖音视频
    代码生成,减少70%的重复劳动
    Log4J配置详解
    linux常用命令
    tomcat修改默认访问首页
    java根据身份证号和获取用户年龄和性别的工具类
  • 原文地址:https://www.cnblogs.com/paulversion/p/11618098.html
Copyright © 2011-2022 走看看