added a connection manager type
parent
512549a07c
commit
a4f3b6f178
@ -0,0 +1,51 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net"
|
||||||
|
)
|
||||||
|
|
||||||
|
var manager = newConnectionManager()
|
||||||
|
|
||||||
|
type connectionManager struct {
|
||||||
|
active []net.Conn
|
||||||
|
connect chan net.Conn
|
||||||
|
disconnect chan net.Conn
|
||||||
|
}
|
||||||
|
|
||||||
|
func newConnectionManager() *connectionManager {
|
||||||
|
m := &connectionManager{
|
||||||
|
active: make([]net.Conn, 0, 10),
|
||||||
|
connect: make(chan net.Conn),
|
||||||
|
disconnect: make(chan net.Conn),
|
||||||
|
}
|
||||||
|
go m.run()
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *connectionManager) run() {
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case conn := <-m.connect:
|
||||||
|
m.active = append(m.active, conn)
|
||||||
|
case conn := <-m.disconnect:
|
||||||
|
m.removeConnection(conn)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *connectionManager) Add(conn net.Conn) {
|
||||||
|
m.connect <- conn
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *connectionManager) Remove(conn net.Conn) {
|
||||||
|
m.disconnect <- conn
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *connectionManager) removeConnection(conn net.Conn) {
|
||||||
|
for i, other := range m.active {
|
||||||
|
if conn.RemoteAddr() == other.RemoteAddr() {
|
||||||
|
m.active = append(m.active[:i], m.active[i+1:]...)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,71 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"net"
|
||||||
|
)
|
||||||
|
|
||||||
|
func tcpInterpreter(conn net.Conn, userinput chan string, out chan interface{}, errors chan error) {
|
||||||
|
prompt := func() {
|
||||||
|
io.WriteString(conn, "> ")
|
||||||
|
}
|
||||||
|
prompt()
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case v := <-out:
|
||||||
|
fmt.Fprintln(conn, v)
|
||||||
|
prompt()
|
||||||
|
case err := <-errors:
|
||||||
|
fmt.Fprintf(conn, "error: %v", err)
|
||||||
|
case line := <-userinput:
|
||||||
|
tokens := make(chan token, 32)
|
||||||
|
go lexs(line+"\n", tokens)
|
||||||
|
go evalall(tokens, out, errors, universe)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func runTCPServer() {
|
||||||
|
ln, err := net.Listen("tcp", *tcpAddr)
|
||||||
|
if err != nil {
|
||||||
|
die(err.Error())
|
||||||
|
}
|
||||||
|
for {
|
||||||
|
conn, err := ln.Accept()
|
||||||
|
if err != nil {
|
||||||
|
printErrorMsg(err.Error())
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
go startConnection(conn, manager)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func startConnection(conn net.Conn, m *connectionManager) {
|
||||||
|
m.Add(conn)
|
||||||
|
defer m.Remove(conn)
|
||||||
|
|
||||||
|
out, errors := make(chan interface{}), make(chan error)
|
||||||
|
userinput := make(chan string)
|
||||||
|
|
||||||
|
go tcpInterpreter(conn, userinput, out, errors)
|
||||||
|
|
||||||
|
r := bufio.NewReader(conn)
|
||||||
|
for {
|
||||||
|
line, prefix, err := r.ReadLine()
|
||||||
|
if prefix {
|
||||||
|
fmt.Println("(prefix)")
|
||||||
|
}
|
||||||
|
switch err {
|
||||||
|
case nil:
|
||||||
|
break
|
||||||
|
case io.EOF:
|
||||||
|
return
|
||||||
|
default:
|
||||||
|
printErrorMsg(err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
userinput <- string(line)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue