// NewTransceiver устаналвивает соединение с SMPP-сервером и возвращает его. func NewTransceiver(addr string, eli time.Duration, bindParams smpp.Params, logEntry *logrus.Entry) (*Transceiver, error) { trx, err := smpp.NewTransceiver(addr, eli, bindParams) if err != nil { return nil, err } return &Transceiver{ addr: addr, Transceiver: trx, Logger: logEntry, }, nil }
// Connect устанавливает соединение со всеми адресами SMPP, указанными в свойствах. func (s *SMPP) Connect() { s.mu.Lock() if s.Logger == nil { // инициализируем поддержку лога s.Logger = logrus.NewEntry(logrus.StandardLogger()) } s.send = make(chan *SendMessage) // канал для отправки SMS s.Receive = make(chan interface{}) // канал для получения SMS s.trxs = make(map[string]*Transceiver, len(s.Address)) // список установленных соединений if s.MaxParts > 0 { MaxParts = int(s.MaxParts) // устанавливаем максимально допустимое количество частей SMS } s.mu.Unlock() // формируем параметры авторизации bindParams := smpp.Params{ smpp.SYSTEM_TYPE: "SMPP", smpp.SYSTEM_ID: s.SystemID, smpp.PASSWORD: s.Password, } // устанавливаем соединение со всеми указанными адресами серверов for _, addr := range s.Address { go func(addr string) { logEntry := s.Logger.WithField("smpp", addr) maxErrors := MaxErrors // устанавливаем максимальное количество допустимых ошибок if s.MaxError > 0 { maxErrors = s.MaxError } var lastErrorTime time.Time // время, когда произошла последняя временная ошибка for i := 0; i < maxErrors; i++ { // перезапускаем сервис автоматически в случае ошибок соединения var key string if addr == s.Address[0] { key = "east.bw.sms.link" } else { key = "west.bw.sms.link" } // устанавливаем соединение с SMPP-сервером trx, err := smpp.NewTransceiver(addr, s.EnquireDuration, bindParams) if err != nil { s.Zabbix.Send(key, "0") logEntry.WithError(err).Error("SMPP Connection error") if time.Since(lastErrorTime) > time.Minute*30 { i = 0 // сбрасываем счетчик ошибок, если они были давно } time.Sleep(s.ReconnectDelay) // задержка перед следующей попыткой lastErrorTime = time.Now() // запоминаем время ошибки continue // повторяем еще раз } logEntry.Info("SMPP Connected") go func() { for { s.Zabbix.Send(key, "1") time.Sleep(time.Minute) } }() transceiver := &Transceiver{ addr: addr, Transceiver: trx, Logger: logEntry, } s.mu.Lock() s.trxs[addr] = transceiver s.mu.Unlock() // запускаем обработку сообщений на отправку go transceiver.sending(s.send) // запускаем получение данных с сервера err = transceiver.reading(s.Receive) s.mu.Lock() delete(s.trxs, addr) // удаляем из списка s.mu.Unlock() transceiver.Close() // закрываем, если не закрыт if err != nil { logEntry.WithError(err).Error("SMPP error") } else { break // плановая остановка } logEntry.Warning("SMPP Connection stopped") time.Sleep(s.ReconnectDelay) // задержка перед следующей попыткой lastErrorTime = time.Now() // запоминаем время ошибки } }(addr) } }