mirror of
https://github.com/ergochat/ergo.git
synced 2024-11-22 11:59:40 +01:00
initial commit
This commit is contained in:
commit
a427e2bb47
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
pkg
|
||||||
|
bin
|
||||||
|
goircd
|
11
goircd.go
Normal file
11
goircd.go
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
package main
|
||||||
|
// http://tools.ietf.org/html/rfc1459
|
||||||
|
|
||||||
|
import (
|
||||||
|
"irc"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
server := irc.NewServer()
|
||||||
|
server.Listen(":6697")
|
||||||
|
}
|
28
src/irc/client.go
Normal file
28
src/irc/client.go
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
package irc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
type Client struct {
|
||||||
|
conn net.Conn
|
||||||
|
ch chan Message
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewClient(conn net.Conn) *Client {
|
||||||
|
return &Client{conn, NewMessageChan(NewStringChan(conn))}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write messages from the client to the server.
|
||||||
|
func (c *Client) Communicate(server chan Message) {
|
||||||
|
for message := range c.ch {
|
||||||
|
message.client = c
|
||||||
|
server <- message
|
||||||
|
}
|
||||||
|
c.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) Close() {
|
||||||
|
c.conn.Close()
|
||||||
|
}
|
46
src/irc/net.go
Normal file
46
src/irc/net.go
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
package irc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"log"
|
||||||
|
"net"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Adapt `net.Conn` to a `chan string`.
|
||||||
|
func NewStringChan(conn net.Conn) chan string {
|
||||||
|
ch := make(chan string)
|
||||||
|
rw := bufio.NewReadWriter(bufio.NewReader(conn), bufio.NewWriter(conn))
|
||||||
|
|
||||||
|
done := make(chan bool)
|
||||||
|
go func() {
|
||||||
|
<- done
|
||||||
|
close(ch)
|
||||||
|
}()
|
||||||
|
|
||||||
|
// conn -> ch
|
||||||
|
go func() {
|
||||||
|
for {
|
||||||
|
line, err := rw.ReadString('\n')
|
||||||
|
if err != nil {
|
||||||
|
log.Print("StringChan[read]: %v", err)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
ch <- line
|
||||||
|
}
|
||||||
|
done <- true
|
||||||
|
}()
|
||||||
|
|
||||||
|
// ch -> conn
|
||||||
|
go func() {
|
||||||
|
for str := range ch {
|
||||||
|
if _, err := rw.WriteString(str + "\r\n"); err != nil {
|
||||||
|
log.Print("StringChan[write]: %v", err)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
rw.Flush()
|
||||||
|
}
|
||||||
|
done <- true
|
||||||
|
}()
|
||||||
|
|
||||||
|
return ch
|
||||||
|
}
|
43
src/irc/protocol.go
Normal file
43
src/irc/protocol.go
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
package irc
|
||||||
|
|
||||||
|
import (
|
||||||
|
)
|
||||||
|
|
||||||
|
type Message struct {
|
||||||
|
line string
|
||||||
|
client *Client
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Message) Encode() string {
|
||||||
|
return m.line
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Adapt `chan string` to a `chan Message`.
|
||||||
|
func NewMessageChan(strch chan string) chan Message {
|
||||||
|
msgch := make(chan Message)
|
||||||
|
|
||||||
|
done := make(chan bool)
|
||||||
|
go func() {
|
||||||
|
<- done
|
||||||
|
close(msgch)
|
||||||
|
}()
|
||||||
|
|
||||||
|
// str -> msg
|
||||||
|
go func() {
|
||||||
|
for str := range strch {
|
||||||
|
msgch <- Message{str, nil}
|
||||||
|
}
|
||||||
|
done <- true
|
||||||
|
}()
|
||||||
|
|
||||||
|
// msg -> str
|
||||||
|
go func() {
|
||||||
|
for message := range msgch {
|
||||||
|
strch <- message.Encode()
|
||||||
|
}
|
||||||
|
done <- true
|
||||||
|
}()
|
||||||
|
|
||||||
|
return msgch
|
||||||
|
}
|
44
src/irc/server.go
Normal file
44
src/irc/server.go
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
package irc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
"net"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Server struct {
|
||||||
|
ch chan Message
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewServer() *Server {
|
||||||
|
server := Server{make(chan Message)}
|
||||||
|
go server.Receive()
|
||||||
|
return &server
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Server) Listen(addr string) {
|
||||||
|
listener, err := net.Listen("tcp", addr)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("Server.Listen: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for {
|
||||||
|
conn, err := listener.Accept()
|
||||||
|
if err != nil {
|
||||||
|
log.Print("Server.Listen: %v", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
client := NewClient(conn)
|
||||||
|
go client.Communicate(s.ch)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Server) Receive() {
|
||||||
|
for message := range s.ch {
|
||||||
|
log.Print("Server.Receive: %v", message.line)
|
||||||
|
message.client.ch <- Message{"pong: " + message.line, nil}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Server) Close() {
|
||||||
|
close(s.ch)
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user