Chinaunix首页 | 论坛 | 博客
  • 博客访问: 709536
  • 博文数量: 90
  • 博客积分: 803
  • 博客等级: 准尉
  • 技术积分: 1041
  • 用 户 组: 普通用户
  • 注册时间: 2012-05-24 13:42
文章分类

全部博文(90)

文章存档

2020年(4)

2019年(4)

2018年(9)

2017年(11)

2016年(11)

2015年(6)

2014年(3)

2013年(28)

2012年(14)

分类: Web开发

2019-07-16 20:03:48


点击(此处)折叠或打开

  1. package main

  2. import (
  3.     "bufio"
  4.     "bytes"
  5.     "fmt"
  6.     "net"
  7.     "sync"
  8.     "time"
  9. )

  10. var connMap map[string]*Heart = make(map[string]*Heart)

  11. var rwLock *sync.RWMutex = new(sync.RWMutex)

  12. var msgChan chan *Message = make(chan *Message, 100)

  13. var addConnChan chan *Heart = make(chan *Heart,1)

  14. var exitConnChan chan *Heart = make(chan *Heart,1)

  15. func main() {

  16.     //新增连接
  17.     go func() {
  18.         for c := range addConnChan {
  19.             connMap[c.conn.RemoteAddr().String()] = c
  20.         }
  21.     }()
  22.     //退出连接
  23.     go func() {
  24.         for c := range exitConnChan {
  25.             delete(connMap, c.conn.RemoteAddr().String())
  26.         }
  27.     }()
  28.     //消息推送
  29.     go func() {
  30.         //遍历消息管道
  31.         for m := range msgChan {
  32.             for oneConn := range connMap {
  33.                 if connMap[oneConn].conn.RemoteAddr().String() != m.conn.RemoteAddr().String() {
  34.                     _, err := connMap[oneConn].conn.Write([]byte(m.message))
  35.                     if err == nil {
  36.                         //更新最后访问时间
  37.                         connMap[oneConn].upTime()
  38.                     }
  39.                 }
  40.             }
  41.         }

  42.     }()
  43.     //心跳检测
  44.     go func() {
  45.         //定时器
  46.         timer := time.NewTimer(time.Duration(30) * time.Second)
  47.         for {
  48.             select {
  49.             case <-timer.C:
  50.                 fmt.Println("timer up!")
  51.                 currTime := time.Now()
  52.                 fmt.Println("当前时间", currTime.Format("2006-01-02 15:04:05"))
  53.                 for oneConn := range connMap {
  54.                     //往客户端循环发送 心跳 如果30秒内发生过通讯的就不需要了
  55.                     cha := currTime.Unix() - connMap[oneConn].lastUpTime
  56.                     if cha > 30 {
  57.                         connTime := time.Unix(connMap[oneConn].lastUpTime, 0)
  58.                         fmt.Println("连接:", connMap[oneConn].conn.RemoteAddr().String(), ",最后更新时间:", connTime.Format("2006-01-02 15:04:05"))
  59.                         _, err := connMap[oneConn].conn.Write([]byte("ping"))
  60.                         if err != nil {
  61.                             fmt.Println("连接断开", connMap[oneConn].conn.RemoteAddr().String())
  62.                             delete(connMap, oneConn)
  63.                         } else {
  64.                             connMap[oneConn].upTime()
  65.                         }
  66.                     }
  67.                 }
  68.                 //重新调度
  69.                 timer.Reset(time.Duration(30) * time.Second)
  70.             }
  71.         }
  72.     }()

  73.     l, err := net.Listen("tcp", "0.0.0.0:8088")
  74.     if err != nil {
  75.         panic(err)
  76.     }
  77.     for {
  78.         conn, err := l.Accept()
  79.         if err != nil {
  80.             fmt.Println("连接错误", err)
  81.         } else {
  82.             go func(conn net.Conn) {

  83.                 defer func(conn net.Conn){
  84.                     exitConnChan <- &Heart{
  85.                         conn: conn,
  86.                         lastUpTime: time.Now().Unix(),
  87.                     }
  88.                     conn.Close()
  89.                     fmt.Println("关闭")
  90.                 }(conn)


  91.                 fmt.Println("新连接:", conn.RemoteAddr())
  92.                 buffer := new(bytes.Buffer)
  93.                 s := "welcome " + conn.RemoteAddr().String() + "!"

  94.                 buffer.WriteString(s)
  95.                 conn.Write(buffer.Bytes())
  96.                 
  97.                 msgChan <- &Message{conn:conn,message:s}

  98.                 //重置缓冲区
  99.                 buffer.Reset()

  100.                 addConnChan <- &Heart{
  101.                     conn: conn,
  102.                     lastUpTime: time.Now().Unix(),
  103.                 }

  104.                 fmt.Printf("connList %v ", connMap)

  105.                 fmt.Println("在线人数", len(connMap))

  106.                 //分隔符解析
  107.                 input := bufio.NewScanner(conn)
  108.                 for input.Scan() {
  109.                     fmt.Println(input.Text())

  110.                     buffer.WriteString(conn.RemoteAddr().String())
  111.                     buffer.WriteString(":")
  112.                     buffer.Write(input.Bytes())
  113.                     buffer.WriteString("\r\n")

  114.                     msgChan <- &Message{conn:conn,message:buffer.String()}

  115.                     //重置缓冲区
  116.                     buffer.Reset()
  117.                 }
  118.             }(conn)
  119.         }
  120.     }

  121. }

点击(此处)折叠或打开

  1. package main

  2. import (
  3.     "net"
  4. )

  5. type Message struct {
  6.     conn net.Conn // tcp 连接
  7.     message    string //消息内容
  8. }


点击(此处)折叠或打开

  1. package main

  2. import (
  3.     "net"
  4.     "time"
  5. )

  6. type Heart struct {
  7.     conn net.Conn // tcp 连接
  8.     lastUpTime int64 //最后更新时间
  9. }

  10. func (h *Heart) upTime() {
  11.     h.lastUpTime = time.Now().Unix()
  12. }


阅读(448) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~