Closed usmonzodasomon closed 1 month ago
Hi,
Broken pipe points to a network issue, the library should handle reconnect automatically if set correctly. Can you share your getSettings() function ?
Thanks
Yes, sure:
func getSettings(handler handler.Handler) gosmpp.Settings { return gosmpp.Settings{ EnquireLink: 15 time.Second,
ReadTimeout: 30 * time.Second,
OnSubmitError: func(p pdu.PDU, err error) {
logger.Logger.Error(fmt.Sprintf("SubmitPDU error: %s", err.Error()))
logger.Logger.Debug(fmt.Sprintf("%+v\n", p))
},
OnReceivingError: func(err error) {
logger.Logger.Error(fmt.Sprintf("Receiving error: %s", err.Error()))
},
OnRebindingError: func(err error) {
logger.Logger.Error(fmt.Sprintf("Rebinding error: %s", err.Error()))
},
OnAllPDU: handler.HandlePDU(),
OnClosed: func(state gosmpp.State) {
logger.Logger.Info(fmt.Sprintf("Session closed: %s", state.String()))
},
}
}
Ok, OnSubmitError is being called because the network is down and you cant submit anymore.
OnSubmitError: func(p pdu.PDU, err error) {
logger.Logger.Error(fmt.Sprintf("SubmitPDU error: %s", err.Error()))
logger.Logger.Debug(fmt.Sprintf("%+v\n", p))
},
When using OnAllPDU
, all PDUs need to be handled by the client. Are you responding to all PDUs, even enquire_links ?
func handlePDU() func(pdu.PDU) (pdu.PDU, bool) {
return func(p pdu.PDU) (pdu.PDU, bool) {
switch pd := p.(type) {
case *pdu.Unbind:
...
case *pdu.EnquireLink:
fmt.Println("EnquireLink Received")
return pd.GetResponse(), false
...
}
}
I only respond to these PDUs:
func HandlePDU() func(pdu.PDU) (pdu.PDU, bool) {
return func(p pdu.PDU) (pdu.PDU, bool) {
switch pd := p.(type) {
case *pdu.Unbind:
return h.Unbind(pd)
case *pdu.DeliverSM:
return h.DeliverSM(pd)
case *pdu.QuerySMResp:
return h.QuerySMResp(pd)
case *pdu.DataSMResp:
return h.DataSMResp(pd)
}
return nil, false
}
}
The enquire_link
is a bind keep alive mechanism, your tcp stream would disconnect if no traffic after your timeout value of 30 seconds.
Here are my recommendation:
as to why it doesn't reconnect, that I do not know.
Thank you for your reply. I'm thinking of adding EnquireLink processing, please help me with this: should I return an answer this way:
case *pdu.EnquireLink:
return pd.GetResponse(), false
, or thus:
case *pdu.EnquireLink:
return pd.GetResponse(), true
thanks!
I added response to EnquireLink but it didn't solve my problem. At the moment, my OnAllPDU function looks like this:
func (h *Handler) Handle PDU() func(pdu.PDU) (pdu.PDU, bool) {
return func(pdu.PDU) (pdu.PDU, bool) {
switch pd := p.(type) {
case *pdu.Unbind:
return h.Unbind(pd)
case *pdu.DeliverSM:
return h.DeliverSM(pd)
case *pdu.QuerySMResp:
return h.QuerySMResp(pd)
case *pdu.DataSMResp:
return h.DataSMResp(pd)
case *pdu.EnquireLink:
return pd.GetResponse(), true
}
return nil, false
}
}
I am also sending you my smpp settings:
func getSettings(handler *handler.Handler) gosmpp.Settings {
return gosmpp.Settings{
EnquireLink: 30 * time.Second,
ReadTimeout: 60 * time.Second,
OnSubmitError: func(p pdu.PDU, err error) {
logger.Logger.Error(fmt.Sprintf("SubmitPDU error: %s", err.Error()))
logger.Logger.Debug(fmt.Sprintf("%+v\n", p))
},
OnReceivingError: func(err error) {
logger.Logger.Error(fmt.Sprintf("Receiving error: %s", err.Error()))
},
OnRebindingError: func(err error) {
logger.Logger.Error(fmt.Sprintf("Rebinding error: %s", err.Error()))
},
OnAllPDU: handler.HandlePDU(),
OnClosed: func(state gosmpp.State) {
logger.Logger.Info(fmt.Sprintf("Session closed: %s", state.String()))
},
}
}
(I increased the ReadTimeout by 60 seconds)
The return bool
is if you want to close the bind, herefor by returning true
, you are closing the bind.
You should only return true
for Unbind request.
Thanks, I changed it to false, I'll report the results later.
As far as I can reason, the EnquireLink request in my case is sent every 30 seconds. I wonder why the connection is not terminated immediately, but after a few hours.
Hello, thank you for your help. I added the EnquireLink processing and I don't have the error anymore. I will send my handler below just in case:
func (h *Handler) Handle PDU() func(pdu.PDU) (pdu.PDU, bool) {
return func(pdu.PDU) (pdu.PDU, bool) {
switch pd := p.(type) {
case *pdu.Unbind:
return h.Unbind(pd)
case *pdu.DeliverSM:
return h.DeliverSM(pd)
case *pdu.QuerySMResp:
return h.QuerySMResp(pd)
case *pdu.DataSMResp:
return h.DataSMResp(pd)
case *pdu.EnquireLink:
return pd.GetResponse(), false
}
return nil, false
}
}
Hello, I am getting the error: SubmitPDU error: write tcp smsc_ip_and_port->server_ip_port: write: broken pipe. The value of the rebinding Interval = 5 seconds:
Restarting the program solves the problem for a while. Please help me.