Highly-opinionated (ex-bullshit-free) MTPROTO proxy for Telegram. If you use v1.0 or upgrade broke you proxy, please read the chapter Version 2
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

connection_hub.go 1.8KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. package hub
  2. import (
  3. "time"
  4. "github.com/9seconds/mtg/protocol"
  5. )
  6. const hubGCEvery = time.Minute
  7. type connectionHubRequest struct {
  8. request *protocol.TelegramRequest
  9. response chan<- *connection
  10. }
  11. type connectionHub struct {
  12. sockets map[int]*connection
  13. channelBrokenSockets chan int
  14. channelConnectionRequests chan *connectionHubRequest
  15. channelReturnConnections chan *connection
  16. }
  17. func (c *connectionHub) run() {
  18. ticker := time.NewTicker(hubGCEvery)
  19. defer ticker.Stop()
  20. for {
  21. select {
  22. case <-ticker.C:
  23. c.runGC()
  24. case request := <-c.channelConnectionRequests:
  25. c.runConnectionRequest(request)
  26. case id := <-c.channelBrokenSockets:
  27. c.runBrokenSocket(id)
  28. case conn := <-c.channelReturnConnections:
  29. c.runReturnConnection(conn)
  30. }
  31. }
  32. }
  33. func (c *connectionHub) runGC() {
  34. for key, conn := range c.sockets {
  35. switch {
  36. case conn.closed():
  37. delete(c.sockets, key)
  38. case conn.idle():
  39. conn.shutdown()
  40. delete(c.sockets, key)
  41. return
  42. }
  43. }
  44. }
  45. func (c *connectionHub) runConnectionRequest(req *connectionHubRequest) {
  46. for key, conn := range c.sockets {
  47. delete(c.sockets, key)
  48. if !conn.closed() {
  49. req.response <- conn
  50. close(req.response)
  51. return
  52. }
  53. }
  54. if conn, err := newConnection(req.request, c); err == nil {
  55. req.response <- conn
  56. }
  57. close(req.response)
  58. }
  59. func (c *connectionHub) runBrokenSocket(id int) {
  60. delete(c.sockets, id)
  61. }
  62. func (c *connectionHub) runReturnConnection(conn *connection) {
  63. c.sockets[conn.id] = conn
  64. }
  65. func newConnectionHub() *connectionHub {
  66. rv := &connectionHub{
  67. sockets: map[int]*connection{},
  68. channelBrokenSockets: make(chan int, 1),
  69. channelConnectionRequests: make(chan *connectionHubRequest),
  70. channelReturnConnections: make(chan *connection, 1),
  71. }
  72. go rv.run()
  73. return rv
  74. }