Golang tcp socket read дает EOF в конечном итоге

У меня есть проблема чтения из сокета. Есть экземпляр звездочки, работающий с большим количеством вызовов (10-60 минут), и я пытаюсь читать и обрабатывать события CDR, связанные с этими вызовами (подключенными к AMI).

Вот библиотека, которую я использую (не моя, но была нажата на fork из-за ошибок) https://github.com/warik/gami

Его довольно простое, главное действие идет в gami.go - readDispatcher.

buf := make([]byte, _READ_BUF) // read buffer for { rc, err := (*a.conn).Read(buf)

Итак, есть TCPConn (a.conn) и буфер с размером 1024, на который я читаю сообщения из сокета. Пока что так хорошо, но в конечном итоге время от времени (это время может варьироваться от 10 минут до 5 часов независимо от количества данных, которое поступает через сокет). Операция чтения не работает с ошибкой io.EOF. Я пытаюсь снова подключиться и повторно подключиться, но это также невозможно - время соединения сократилось, поэтому меня заставили ждать около 40-60 секунд, и на этот раз для меня очень важно, я теряю много данных из-за задержки, Я искал походы в Google, читая источники и пробовал много всего - ничего. Самое странное, что простой сокет, открытый в python или php, не подводит.

  • Возможно ли, что проблема из-за отсутствия файловых дескрипторов для представления сокета на моей машине или на сервере звездочки?
  • Возможно ли, что проблема в конфигурации звездочки (потому что у меня есть еще одна звездочка, на которой эта проблема не воспроизводится, но также, у меня есть меньше вызовов на последнем)?
  • Возможно ли, что проблема на моем пути справиться с подключением сокетов или с Go вообще?

go версия go1.2.1 linux/amd64

asterisk 1.8

2 ответа

Хорошо, проблема была в переполнении буфера ОС. Как оказалось, было много данных для обработки.

Итак, были три возможных способа исправить это:

  • увеличить объем буфера сокета
  • как-то ускорить процесс, который забирает данные из сокета
  • более низкий объем данных или частота

То, что gami по умолчанию читает все данные из звездочки. И я читал их все и отфильтровывал их после фактической операции чтения. Согласно тому, что приложение для прослушивания AMI работает на довольно плохом ПК, оказалось, что он просто не может прочитать все данные до того, как будет открыта емкость буфера. Но возможно получить только определенные события, отправив действие "События" в AMI и указав желаемую "EventMask ". Итак, мое решение было сделать это. И создайте разные соединения для разных типов событий.


Обновите последнюю звездочку. Там была ошибка, когда AMI посылает много данных.

Для проверки проблемы вы отправили команду ami, например "COMMAND sip show peers" (или любую другую длинную команду вывода), и увидите результат.

licensed under cc by-sa 3.0 with attribution.