Skip to content

Instantly share code, notes, and snippets.

@mojocn
Last active March 24, 2021 03:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mojocn/a11430861cdc8d7ab96c40cf3e429694 to your computer and use it in GitHub Desktop.
Save mojocn/a11430861cdc8d7ab96c40cf3e429694 to your computer and use it in GitHub Desktop.
a simple chat engine of golang
package chatengine
import (
"fmt"
"net"
)
type ConnHub struct {
cap int
pool map[net.Addr]net.Conn
ops chan func(map[net.Addr]net.Conn)
}
func NewConnHub(cap int) *ConnHub {
return &ConnHub{
cap: cap,
pool: make(map[net.Addr]net.Conn, cap),
ops: make(chan func(map[net.Addr]net.Conn)),
}
}
func (v *ConnHub) Join(conn net.Conn) {
v.ops <- func(m map[net.Addr]net.Conn) {
m[conn.RemoteAddr()] = conn
}
}
func (v *ConnHub) Leave(addr net.Addr) {
v.ops <- func(m map[net.Addr]net.Conn) {
delete(m, addr)
}
}
func (v *ConnHub) SendMsgPublic(msg []byte) error {
results := make(chan error, 1)
v.ops <- func(m map[net.Addr]net.Conn) {
for _, c := range m {
_, err := c.Write(msg)
if err != nil {
results <- err
return
}
}
results <- nil
}
return <-results
}
func (v *ConnHub) SendMsgPrivate(addr net.Addr, msg []byte) error {
results := make(chan net.Conn, 1)
v.ops <- func(m map[net.Addr]net.Conn) {
results <- m[addr]
}
conn := <-results
if conn == nil {
return fmt.Errorf("client of %s is not registered", addr)
}
_, err := conn.Write(msg)
return err
}
func (v *ConnHub) Loop() {
for op := range v.ops {
op(v.pool)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment