Keine Beschreibung

netconn.go 1.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. package main
  2. import (
  3. "bufio"
  4. "fmt"
  5. "io"
  6. "net"
  7. )
  8. type NetConn struct {
  9. netReader *bufio.Reader
  10. conn net.Conn
  11. netReadChan chan rune
  12. hangup chan struct{}
  13. paused bool
  14. connected bool
  15. }
  16. func NewNetConn(addr string) (*NetConn, error) {
  17. c := &NetConn{}
  18. var err error
  19. c.conn, err = net.Dial("tcp", addr)
  20. if err != nil {
  21. return nil, err
  22. }
  23. c.connected = true
  24. c.netReader = bufio.NewReader(c.conn)
  25. c.netReadChan = make(chan rune)
  26. c.hangup = make(chan struct{})
  27. c.paused = false
  28. go func() {
  29. for {
  30. r, l, err := c.netReader.ReadRune()
  31. if err != nil && err != io.EOF {
  32. c.cleanup()
  33. return
  34. }
  35. if c.paused || l == 0 {
  36. select {
  37. case <-c.hangup:
  38. c.cleanup()
  39. return
  40. default: // discard
  41. }
  42. } else {
  43. select {
  44. case c.netReadChan <- r:
  45. case <-c.hangup:
  46. c.cleanup()
  47. return
  48. }
  49. }
  50. }
  51. }()
  52. return c, nil
  53. }
  54. func (c *NetConn) Write(r rune) error {
  55. if c == nil {
  56. return fmt.Errorf("NetConn not initialized")
  57. }
  58. _, err := c.conn.Write([]byte(string(r)))
  59. if err != nil {
  60. close(c.hangup)
  61. }
  62. return err
  63. }
  64. func (c *NetConn) Hangup() {
  65. if c == nil {
  66. return
  67. }
  68. c.conn.Close()
  69. close(c.hangup)
  70. }
  71. func (c *NetConn) cleanup() {
  72. close(c.netReadChan)
  73. c.connected = false
  74. }
  75. func (c *NetConn) Pause() {
  76. if c == nil {
  77. return
  78. }
  79. c.paused = true
  80. }
  81. func (c *NetConn) Resume() {
  82. if c == nil {
  83. return
  84. }
  85. c.paused = false
  86. }
  87. func (c *NetConn) OutputChannel() chan rune {
  88. if c == nil {
  89. return nil
  90. }
  91. return c.netReadChan
  92. }
  93. func (c *NetConn) Connected() bool {
  94. if c == nil {
  95. return false
  96. }
  97. return c.connected
  98. }