Пример #1
0
// 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
}
Пример #2
0
// 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)
	}
}