-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsession.go
More file actions
114 lines (103 loc) · 2.49 KB
/
session.go
File metadata and controls
114 lines (103 loc) · 2.49 KB
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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
package main
import (
"bufio"
"fmt"
"io"
"log"
"net"
"sync"
)
type Session struct {
Id int64
exit chan bool
connection net.Conn
from_muck chan<- Message
to_muck <-chan Message
}
func (s *Session) SetUp(UserID int64, from_muck chan<- Message, to_muck <-chan Message) {
s.Id = UserID
s.from_muck = from_muck
s.to_muck = to_muck
s.exit = make(chan bool)
conn, err := net.Dial("tcp", "furrymuck.com:8888")
if err != nil {
log.Panic(err)
}
log.Printf("Connection with muck established for user %s", UserID)
s.connection = conn
}
func (s *Session) Stop() {
log.Printf("Closing muck session of user %s", s.Id)
close(s.exit)
}
func (s Session) Work() {
log.Printf("Processing the connection of user %s", s.Id)
exitWait := new(sync.WaitGroup)
exitWait.Add(2)
go func() {
defer func() {
exitWait.Done()
log.Printf("Reading from muck for user %s was stopped.", s.Id)
}()
s.StartReading()
}()
go func() {
defer func() {
exitWait.Done()
log.Printf("Writing to muck for user %s was stopped.", s.Id)
}()
s.StartWriting()
}()
exitWait.Wait()
log.Printf("Processing for user %s was stopped.", s.Id)
}
func (s *Session) StartReading() {
reader := bufio.NewReader(s.connection)
for {
text, err := reader.ReadString('\n')
if len(text) > 0 {
log.Printf("Got text from muck for user %s: %s", s.Id, text)
s.from_muck <- Message{s.Id, text}
}
if err == io.EOF {
log.Printf("Connection of user %s was closed by server.", s.Id)
s.connection.Close()
close(s.exit)
return
} else if err != nil {
log.Printf("Error wile reading from muck for user %s: %s. Closing connection.", s.Id, err)
s.connection.Close()
close(s.exit)
return
}
// XXX: Вообще, это не самое лучшее решение, так как мы ждём данных
// из соединения перед тем как его закрыть.
// Я не знаю как тут неблокирующе читать из сокета, поэтому пока вот так.
select {
case <-s.exit:
{
log.Printf("Closing connection for user %s", s.Id)
s.connection.Close()
return
}
default:
}
}
}
func (s *Session) StartWriting() {
for {
select {
case message := <-s.to_muck:
{
log.Printf("Sending info of user %s to muck: %s", message.UserId, message.Text)
fmt.Fprintf(s.connection, message.Text+"\n")
}
case <-s.exit:
{
log.Printf("Stopping reading for user %s", s.Id)
return
}
default:
}
}
}