/
socket-chat-client.go
85 lines (81 loc) · 2.08 KB
/
socket-chat-client.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
//++++++++++++++++++++++++++++++++++++++++
// 《Go Web编程实战派从入门到精通》源码
//++++++++++++++++++++++++++++++++++++++++
// Author:廖显东(ShirDon)
// Blog:https://www.shirdon.com/
// 仓库地址:https://gitee.com/shirdonl/goWebActualCombat
// 仓库地址:https://github.com/shirdonl/goWebActualCombat
//++++++++++++++++++++++++++++++++++++++++
package main
import (
"bufio"
"fmt"
"net"
"os"
"time"
)
func main() {
server := "127.0.0.1:8086"
tcpAddr, err := net.ResolveTCPAddr("tcp4", server)
if err != nil {
Log(os.Stderr, "Fatal error:", err.Error())
os.Exit(1)
}
conn, err := net.DialTCP("tcp", nil, tcpAddr)
if err != nil {
Log("Fatal error:", err.Error())
os.Exit(1)
}
Log(conn.RemoteAddr().String(), "connect success!")
Sender(conn)
Log("end")
}
func Sender(conn *net.TCPConn) {
defer conn.Close()
sc := bufio.NewReader(os.Stdin)
go func() {
t := time.NewTicker(time.Second) //创建定时器,用来实现定期发送心跳包给服务端
defer t.Stop()
for {
<-t.C
_, err := conn.Write([]byte("1"))
if err != nil {
fmt.Println(err.Error())
return
}
}
}()
name := ""
fmt.Println("请输入聊天昵称") //用户聊天的昵称
fmt.Fscan(sc, &name)
msg := ""
buffer := make([]byte, 1024)
_t := time.NewTimer(time.Second * 5) //创建定时器,每次服务端发送消息就刷新时间
defer _t.Stop()
go func() {
<-_t.C
fmt.Println("服务器出现故障,断开链接")
return
}()
for {
go func() {
for {
n, err := conn.Read(buffer)
if err != nil {
return
}
_t.Reset(time.Second * 5) //收到消息就刷新_t定时器,如果time.Second*5时间到了,那么就会<-_t.C就不会阻塞,代码会往下走,return结束
if string(buffer[0:1]) != "1" { //心跳包消息定义为字符串"1",不需要打印出来
fmt.Println(string(buffer[0:n]))
}
}
}()
fmt.Fscan(sc, &msg)
i := time.Now().Format("2006-01-02 15:04:05")
conn.Write([]byte(fmt.Sprintf("%s\n\t%s: %s", i, name, msg))) //发送消息
}
}
func Log(v ...interface{}) {
fmt.Println(v...)
return
}