fiorix / go-smpp Goto Github PK
View Code? Open in Web Editor NEWSMPP 3.4 Protocol for the Go programming language
License: MIT License
SMPP 3.4 Protocol for the Go programming language
License: MIT License
I am looking to represent PDUs as JSON, and the most simple implementation doesn't work since codec's fields are private:
p := pdu.NewDeliverSM()
fields := p.Fields()
fields.Set(pdufield.ShortMessage, "ShortMessage")
bytes, err := json.Marshal(p)
log.Println(string(bytes))
Outputs: {}
. I implemented my own func (pdu *codec) MarshalJSON() ([]byte, error)
and it works only if I don't encode TLVMap
, since it returns unsupported type
. I don't mind this error since I can implement its own MarshalJSON()
as well.
The problem I am facing is with UnmarshalJSON()
. Since I am trying to get back a pdu.Body
and it is an interface, I need to unmarshal first to the underlying type (codec) but it is a private struct. What do you think about exposing Codec
and its fields? Out of curiosity, what was the purpose of having pdu.Body
as an interface?
There are realization in this repository
Maybe you can use this.
When submitting a message and connection drops middle sending a crash can happen since response PDU is empty here: https://github.com/fiorix/go-smpp/blob/master/smpp/transmitter.go#L294
At this point "resp" var contains: &{ not connected}, so I could fix this just by checking for nil and return the error inside the resp var if it exists, if you think it should be fixed somewhere else please let me know.
Hi
How do you set the address range, an upstream smpp server requires us to set the address range as 100 on the bind.
How is this achieved in the code.
These are the parameters I have to connect with:
*Apologies, I am still finding my way around Go, (the obvious might not be that obvious to me right now)
The method Map.Set() has a switch statement on the type of the value passed, but in the case of RegisteredDelivery
the type is DeliverySetting
which will not be covered by this switch causing it to not be set in the map. We can either change the DeliverySettings
to uint8
or add the extra type case in the switch statement.
Many thanks!
Dears Am not able to send a msg to anyone if the Src was letters instead of numbers
Can you guide me through the solution pleaaase 🥺
Hello,
Here is my code that initiate the connection to the SMPP server :
var trx *smpp.Transceiver
func Bind() error {
trx = &smpp.Transceiver{
Addr: "localhost:2375",
}
conn := trx.Bind()
if connStatus := <-conn ; connStatus.Status() != smpp.Connected {
return connStatus.Error()
}
return nil
}
func Stop() error {
return trx.Close()
}
I call the Stop()
function when I catch the Interrupt signal.
I'd like to send an Ubind command to the SMPP server before closing the connection.
Is there a way to do that ?
It would be great to have something like that :
func Stop() error {
return trx.Unbind()
}
Thanks
i bind smpp with handler, everytime i send submitSM, submitSMRespose always receive on handler that i register before not in return value of submitSM. how to get submitSMResponse from return value of submitSM even listen a message handler?
Можете подсказать делаю пакет для API своего https://play.golang.org/p/ES7Fv1tuzJz . Но ошибка идетъ
err con
2018/02/06 17:49:59 SMPP connection status: Connected
err con
2018/02/06 17:50:33 SMPP connection status: Connected
err con
2018/02/06 17:51:22 SMPP connection status: Connected
в связи с чем такая ошибка может возникать
I am using the transceiver to submit a SM, and receiving the response back successfully, but I also have a handler that wants to process the SubmitSMResp. Right now, it seems that it doesn't get passed to the handler, am I correct?
Why we have 2 different Conn interfaces(smpptest.Conn and smpp.Conn). And why we can't use simple net.Conn?
Line 30 on pdufield/tlvbody.go
, SerializeTo function doesn't write anything to io.Writer.
In transmitter.go file rc != nil,which eventually not calling the f(p). After changing to else if to if ,submit_smresp event is being received in the transceiver callback. Could you please help me why its being written like this?
seq := p.Header().Seq
t.tx.Lock()
rc := t.tx.inflight[seq]
t.tx.Unlock()
if rc != nil {
rc <- &tx{PDU: p}
} else if f != nil {
f(p)
}
I'm wondering is there a way to submit a custom PDU from Transmitter, not using predefined Submit and SubmitLongMsg methods?
E.g getting DELIVER_SM pdu, changing header ID to SUBMIT_SM and pushing it back to SMSC.
From the SMSC I'm connecting to (not sure which SMSC) when submitting to multiple recipients Response Message contains a single ID, but when delivery report is received it has different message IDs for each recipient.
Is there a way to retrieve message ID for each recipient?
Hello,
How could I send a generic_nack PDU to SMS-C when my ESME receive an unsupported PDU ?
Here is the handler that I provide to my Transceiver
:
func handle(p pdu.Body) {
switch p.Header().ID {
case pdu.DeliverSMID:
logger.Infof("Received DeliverSM PDU")
case pdu.UnbindID:
logger.Infof("Received Unbind PDU from SMS-C... shutting down !")
stopGracefully()
default:
nack := pdu.NewGenericNACK()
// TODO: send nack ... but how ?
logger.Errorf("Received unknown pdu: %+v", p)
}
}
Any idea ?
Thanks !
Emmanuel
Hi all,
Noticed that the library, when sending long messages, only returns the data for the last part of the multi-part message. This is due to the function only returning a single ShortMessage in the response:
func (t *Transmitter) SubmitLongMsg(sm *ShortMessage) (*ShortMessage, error) {
I would like to extend this function to return all parts of the multi-part message:
func (t *Transmitter) SubmitLongMsg(sm *ShortMessage) ([]ShortMessage, error) {
We could then keep track of the delivery status (via Delivery-Receipts) of each part of the multi-part message.
Hi,
I am going over SubmitLongMsg and needed access to all response PDUs, but only the last is returned. What was the reasoning behind having ShortMessage
working both as a request and response struct? Why only return the last response PDU?
Thanks!
I think we need to mark some milestone changes with SemVer tags like v1.2.3
.
This would help people with dependency managers like golang/dep
easily control which version of the library they prefer to take.
First of all, Thank you for this awesome plugin.
Is it possible to send WapPush message if this plugin?
I read that you need to set the datacoding to 245 but from the 3 available datacoding types on this plugin i am not sure which one it is if it is any of these at all or is there a way i can set up the Text parameter of the message to switch my need?
Thank you
how to set UDH (user data header) to Transmitter ??
because there is no param in the &smpp.ShortMessage{} ??
how to solve this ??
From my understanding it's not yet possible to write anything over the wire if you use a receiver och transceiver which makes things difficult. Having the possibility to a HandlerFunction is great, but it's not that helpful if you have no way of replying back to the incoming PDU's.
One example being a transceiver where you use tx.Submit(...)
which is great how it's blocking and taking care of responses and response matching for you, but when the DeliverSM finally arrives in the handler there is no way to reply to this with an DeliverSMResp (non that I've found, please correct me if I'm wrong).
My suggestion is to make all connections (Transmitter, Receiver and Transceiver) implement the Writer interface, that way the clients can respond to DeliverSM, send their own DeliverSM (acting as a server) and have their own EnquireLink handling in the future (right now EnquireLink only seems to work if the client initiates it; but the client will never reply to an enquire link from the server).
When using rand for generating reference number for UDH header, Transceiver causes panic because rand is not seeded.
Hi,
I am trying to use (and expand) the server in smpptest. I ran a server and took the sample code for running a client. When I try to submit a ShortMessage with transmitter.Submit()
, I get the error unexpected PDU ID: SubmitSM
which makes sense since the server is only responding back with the same PDU in the EchoHandler
.
In the EchoHandler
, I modified the ID of the PDU to be SubmitSMRespID
by accessing the headers of the request PDU and when I send it back, the client times out. I pinpointed the problem to be in list.go:112
where it complains: not enough data for tag 0x0: want 29554, have 22
.
I would imagine that messing directly with the headers could be a bad idea, so I went ahead and used the function NewSubmitSMResp()
from types.go
to build a the appropriate response in the EchoHandler
. When I sent it back, the client just times out again with no response and I can't pinpoint the cause.
EchoHandler looks like this:
func EchoHandler(conn Conn, m pdu.Body) {
// Approach #1: Send it back as-is
// Approach #2: Modify the ID directly
// m.Header().ID = pdu.SubmitSMRespID
// Approach #3: Send a new response
// m = pdu.NewSubmitSMResp()
err := conn.Write(m)
if err != nil {
fmt.Println(err)
}
}
What am I doing wrong? Or am I missing to implement something? I am quite knew to SMPP so bare with me if there are obvious mistakes I didn't spot.
Thanks!
Hi,
I want to connect multiple clients to server but if one client is connected, unable to connect another client (unable to bind ). Any suggestions please.
Error if more than one client connects :
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x40 pc=0x7a18af]
goroutine 1 [running]:
main.smpp_connection(0xc0000143c0, 0xc, 0xbb8, 0xc000014420, 0x6, 0xc000014470, 0x6, 0x8)
Thanks in advance
Example
I am calling *933*Hello#, mobile operator sends to endpoint.
Endpoint responses "Hi there" to mobile operator and I receive "Hi There"
is possible to do USSD with go-smpp?
Are you guys planning to add support for TLV params in codec ?
Hello, thx for you job.
i have this problem.
i receiving response error - unexpected PDU ID: Deliver SM
there is source
func (t *Transmitter) submitMsg(sm *ShortMessage, p pdu.Body, dataCoding uint8) (*ShortMessage, error) {
f := p.Fields()
f.Set(pdufield.SourceAddr, sm.Src)
f.Set(pdufield.DestinationAddr, sm.Dst)
f.Set(pdufield.ShortMessage, sm.Text)
f.Set(pdufield.RegisteredDelivery, uint8(sm.Register))
// Check if the message has validity set.
if sm.Validity != time.Duration(0) {
f.Set(pdufield.ValidityPeriod, convertValidity(sm.Validity))
}
f.Set(pdufield.ServiceType, sm.ServiceType)
f.Set(pdufield.SourceAddrTON, sm.SourceAddrTON)
f.Set(pdufield.SourceAddrNPI, sm.SourceAddrNPI)
f.Set(pdufield.DestAddrTON, sm.DestAddrTON)
f.Set(pdufield.DestAddrNPI, sm.DestAddrNPI)
f.Set(pdufield.ESMClass, sm.ESMClass)
f.Set(pdufield.ProtocolID, sm.ProtocolID)
f.Set(pdufield.PriorityFlag, sm.PriorityFlag)
f.Set(pdufield.ScheduleDeliveryTime, sm.ScheduleDeliveryTime)
f.Set(pdufield.ReplaceIfPresentFlag, sm.ReplaceIfPresentFlag)
f.Set(pdufield.SMDefaultMsgID, sm.SMDefaultMsgID)
f.Set(pdufield.DataCoding, dataCoding)
resp, err := t.do(p)
if err != nil {
return nil, err
}
sm.resp.Lock()
sm.resp.p = resp.PDU
sm.resp.Unlock()
if resp.PDU == nil {
return nil, fmt.Errorf("unexpected empty PDU")
}
if id := resp.PDU.Header().ID; id != pdu.SubmitSMRespID {
return sm, fmt.Errorf("unexpected PDU ID: %s", id)
}
if s := resp.PDU.Header().Status; s != 0 {
return sm, s
}
return sm, resp.Err
}
may be problem, that outgoing sequence id has same sequence id that and incoming Deliver SM
func (t *Transmitter) do(p pdu.Body) (*tx, error) {
t.cl.Lock()
notbound := t.cl.client == nil
t.cl.Unlock()
if notbound {
return nil, ErrNotBound
}
if t.cl.WindowSize > 0 {
inflight := uint(atomic.AddInt32(&t.tx.count, 1))
defer func(t *Transmitter) { atomic.AddInt32(&t.tx.count, -1) }(t)
if inflight > t.cl.WindowSize {
return nil, ErrMaxWindowSize
}
}
rc := make(chan *tx, 1)
seq := p.Header().Seq
t.tx.Lock()
t.tx.inflight[seq] = rc
t.tx.Unlock()
defer func() {
t.tx.Lock()
delete(t.tx.inflight, seq)
t.tx.Unlock()
}()
err := t.cl.Write(p)
if err != nil {
return nil, err
}
select {
case resp := <-rc:
if resp.Err != nil {
return nil, resp.Err
}
return resp, nil
case <-t.cl.respTimeout():
return nil, ErrTimeout
}
}
may be here deleting happen later
defer func() {
t.tx.Lock()
delete(t.tx.inflight, seq)
t.tx.Unlock()
}()
sorry for my bad english, can you help ?
thank you
Using:
tx := &smpp.Transceiver{
...
}
tx.Bind()
on unstable connection leads to memory leak (sorry for line numbers - issue encountered on old github.com/zpas-lab/go-smpp fork):
github.com/zpas-lab/go-smpp/smpp.(*client).Read(0xc4201264d0, 0xc420e62f58, 0xc40000ac38, 0xc420bdbde8, 0x0)
github.com/zpas-lab/go-smpp/smpp/client.go:170 +0xf8
github.com/zpas-lab/go-smpp/smpp.(*Transmitter).handlePDU(0xc4202d3b68, 0xc4205248a0)
github.com/zpas-lab/go-smpp/smpp/transmitter.go:103 +0x44
created by github.com/zpas-lab/go-smpp/smpp.(*Transceiver).bindFunc
github.com/zpas-lab/go-smpp/smpp/transceiver.go:74 +0x43a
For current code would be:
client.go:225
transmitter.go:118
transceiver.go:80
This happens because transceiver calls go client.Bind()
, in which:
client.BindFunc
is called, which is transceiver.bindFunc
injected, which calls go transmitter.handlePDU
, which calls client.Read
, which waits on client.inbox
channel)err
is returned, break
in l.153 is called, which means there is no send to client.inbox
. close(client.inbox)
is called nowhere, so transceiver.bindFunc
waits foreverIf this scenario repeats, we end up with more and more goroutines (transceiver.bindFunc -> transmitter.handlePDU -> client.Read
) waiting on the client.inbox
channel.
There is another methods to send long messages, like SAR. It would be awesome to support it.
Firstly, thanks for really awesome work. I have used and tested this package for simple sms and it works on smppsim simulator. My real smpp provided wants addrton
,dest_addr_ton
, source_addr_npi
and addr_npi
to be provided. If I send sms without these fields using Submit method it says invalid source address.
Method func (t *Transmitter) Submit(sm *ShortMessage) (*ShortMessage, error)
doesn't support a parmeter to send additional fields along with simple ones. May I suggest a new method with signature:
func (t *Transmitter) SubmitWithFields(sm *ShortMessage, fields map[string]interface{}) (*ShortMessage, error)
I tried implementing above using following code:
// SubmitWithFields sends a short message along with extra pdu fields and returns and updates the given
// sm with the response status. It returns the same sm object.
func (t *Transmitter) SubmitWithFields(sm *ShortMessage, fields map[string]int) (*ShortMessage, error) {
p := pdu.NewSubmitSM()
f := p.Fields()
f.Set(pdufield.SourceAddr, sm.Src)
f.Set(pdufield.DestinationAddr, sm.Dst)
f.Set(pdufield.ShortMessage, sm.Text)
f.Set(pdufield.RegisteredDelivery, uint8(sm.Register))
for k, v := range fields {
err := f.Set(pdufield.Name(k), v)
if err != nil {
return sm, fmt.Errorf("Couldn't set field %s with value %s. Error: %s", k, v, err)
}
}
// Check if the message has validity set.
if sm.Validity != time.Duration(0) {
f.Set(pdufield.ValidityPeriod, convertValidity(sm.Validity))
}
resp, err := t.do(p)
if err != nil {
return nil, err
}
sm.resp.Lock()
sm.resp.p = resp.PDU
sm.resp.Unlock()
if id := resp.PDU.Header().ID; id != pdu.SubmitSMRespID {
return sm, fmt.Errorf("unexpected PDU ID: %s", id)
}
if s := resp.PDU.Header().Status; s != 0 {
return sm, s
}
return sm, resp.Err
}
but when I submit with this method, smppsim disconnects and times out. Is there any better way via which I can send additional fields?
Hey there,
We're going to be running some services with this library that are going to be using a fairly large number of binds. With the current 1 byte reference number the chance of a collision would be relatively high and we'd like to use the alternative header with the 2 byte number. For now we've patched the library to add it in but was wanting to ask if you would accept a PR for it?
Cheers,
Lucian
Looks like decoding process adds one null byte at the start of ShortMessage field.
Example code:
package main
import (
"bytes"
"fmt"
"github.com/fiorix/go-smpp/smpp"
"github.com/fiorix/go-smpp/smpp/pdu"
"github.com/fiorix/go-smpp/smpp/pdu/pdufield"
"github.com/fiorix/go-smpp/smpp/pdu/pdutext"
)
func main(){
sm := &smpp.ShortMessage{
Src: "TEST",
Dst: "+79000005555",
Text: pdutext.UCS2("Hello"),
Register: pdufield.NoDeliveryReceipt,
}
p := pdu.NewDeliverSM()
f := p.Fields()
f.Set(pdufield.SourceAddr, sm.Src)
f.Set(pdufield.DestinationAddr, sm.Dst)
f.Set(pdufield.ShortMessage, sm.Text)
f.Set(pdufield.RegisteredDelivery, uint8(sm.Register))
f.Set(pdufield.ServiceType, sm.ServiceType)
f.Set(pdufield.SourceAddrTON, sm.SourceAddrTON)
f.Set(pdufield.SourceAddrNPI, sm.SourceAddrNPI)
f.Set(pdufield.DestAddrTON, sm.DestAddrTON)
f.Set(pdufield.DestAddrNPI, sm.DestAddrNPI)
f.Set(pdufield.ESMClass, sm.ESMClass)
f.Set(pdufield.ProtocolID, sm.ProtocolID)
f.Set(pdufield.PriorityFlag, sm.PriorityFlag)
f.Set(pdufield.ScheduleDeliveryTime, sm.ScheduleDeliveryTime)
f.Set(pdufield.ReplaceIfPresentFlag, sm.ReplaceIfPresentFlag)
f.Set(pdufield.SMDefaultMsgID, sm.SMDefaultMsgID)
f.Set(pdufield.DataCoding, uint8(sm.Text.Type()))
var b bytes.Buffer
p.SerializeTo(&b)
fmt.Printf("INITIAL PDU: %x\n", b.Bytes())
np, _ := pdu.Decode(bytes.NewBuffer(b.Bytes()))
var nb bytes.Buffer
np.SerializeTo(&nb)
fmt.Printf("DECODED PDU: %x\n", nb.Bytes())
fmt.Printf("INITIAL SM: %x\n", p.Fields()[pdufield.ShortMessage])
fmt.Printf("DECODED SM: %x\n", np.Fields()[pdufield.ShortMessage])
}
Output:
$ go run smpp_sample.go
INITIAL PDU: 0000003c000000050000000000000001000000544553540000002b3739303030303035353535000000000000000008000a0000480065006c006c006f
DECODED PDU: 0000003c000000050000000000000001000000544553540000002b3739303030303035353535000000000000000008000a000000480065006c006c00
INITIAL SM: 00480065006c006c006f
DECODED SM: 0000480065006c006c00
I use node-smpp library and I have problems with it.
When I receive a message that has more than 160 latin characters, then the message is divided into parts and instead of letters I accept some characters. For example:
short_message: { udh: <Buffer 05 00 03 4c 02 01>, message: ' nPXNO ePzÅ\n o9ΘDG ÆT ä ù A w \r Asxy 6 Agy Å 0\u001bD. 4 . ΘDG A w $ dP \r eΔ L& s=ö. Ae< & gΔ \r vΘ vY ß ' } }
whenever I send an SMS in Arabic it looks weird
"هلو" => "YìYèYò"
Hi all,
Currently there is no support for GSM7 encoding or packing.
Since most SMPP providers do not support receiving GSM7 packed (septet to octet conversion) requests, I suggest that we add two new codecs:
Encode and pack messages. That means messages should be split after 140-7 bytes (UDH header), since there is the potential for splitting an escaped character (which consists of two bytes) like {
across two parts, we should limit each part to 140-7-1 bytes.
Only encode message, since many SMPP providers will not accept GSM7 packed. That means message should be split after 160-7 bytes (UDH header), since there is the potential for splitting an escaped character (which consists of two bytes) like {
across two parts, we should limit each part to 160-7-1 bytes.
It looks that on each 10 seconds smpp session is re-connected.
2016/07/07 17:58:26 SMPP connection status: Connected
2016/07/07 17:58:26 Received message.
2016/07/07 17:58:31 Received message.
2016/07/07 17:58:36 SMPP connection status: Disconnected
Is this a normal behaviour or it's something unexpected ?
I've tried to compare it with a java library and it looks that is able to accept much more messages then the go library which is suspicious and I'm thinking that some messages are dismissed from go-smpp.
Here is the output from the same host/user/pass from jsmpp (the java library):
Jul 07, 2016 6:05:25 PM TestApp$1 onAcceptDeliverSm Received message.
Jul 07, 2016 6:05:26 PM TestApp$1 onAcceptDeliverSm Received message.
Jul 07, 2016 6:05:26 PM TestApp$1 onAcceptDeliverSm Received message.
Jul 07, 2016 6:05:26 PM TestApp$1 onAcceptDeliverSm Received message.
Jul 07, 2016 6:05:26 PM TestApp$1 onAcceptDeliverSm Received message.
Jul 07, 2016 6:05:26 PM TestApp$1 onAcceptDeliverSm Received message.
Jul 07, 2016 6:05:26 PM TestApp$1 onAcceptDeliverSm Received message.
Jul 07, 2016 6:05:27 PM TestApp$1 onAcceptDeliverSm Received message.
This is how Transceiver is created:
tx := &smpp.Transceiver{
Addr: "20.20.20.20:2775",
User: "mytestuser",
Passwd: "mytestpass",
SystemType: "cp",
EnquireLink: 30 * time.Minute,
Handler: f,
}
I'm trying to send DLR using NewDeliverSM, but with no success. Message is sent, but not recognized as DLR
I tried with:
p := pdu.NewDeliverSM()
p.TLVFields().Set(pdutlv.TagReceiptedMessageID, pdutlv.CString("1234"))
p.TLVFields().Set(pdutlv.TagMessageStateOption, 2)
f := p.Fields()
f.Set(pdufield.SourceAddr, m.Fields()[pdufield.SourceAddr])
f.Set(pdufield.DestinationAddr, m.Fields()[pdufield.DestinationAddr])
f.Set(pdufield.ESMClass, 4)
f.Set(pdufield.ServiceType, m.Fields()[pdufield.ServiceType])
f.Set(pdufield.ProtocolID, 0)
p.Header().Status = 0
p.Header().Seq = m.Header().Seq + 1
f.Set(pdufield.ShortMessage, pdutext.Latin1("id:1234 sub:001 dlvrd:001 submit date:180625012100 done date:180625012101 stat:DELIVRD err:000 text:"))
where f are fields from original SubmitSM, "1234" message @#id
What I'm doing wrong here? Do I need to encode values like pdufield.ESMClass = 4 to other formats?
Any working example will be appreciated
I want to restrict Send() of message during reconnects.
If Bind_tranciever coincide with Submit_sm it causes Bind to fail -- SMSC does not answer on Bind.
Hello everyone.
I've found a "bug" when I use SubmitLongMsg function.
If t.do(p) function returns ErrMaxWindowSize, then SubmitLongMsg terminates and it becomes impossible to send the rest parts of message.
But ErrMaxWindowSize is a minor error and it would be great if SubmitLongMsg entered to sleep mode when this error occured.
I've found the way how to do that:
again:
resp, err := t.do(p)
if err == ErrMaxWindowSize {
time.Sleep(100 * time.Millisecond)
goto again
}
if err != nil {
return nil, err
}
But I don't know how can I calculate ideal sleep mode duration.
Oh! God damn. Maybe need I making semaphore struct and rework t.do function to limit sending messages by my goroutines?
I tried sending larger than one sms content UCS (60+) and Latin(160+) encoded data using ShortMessage struct but it failed on smpp service provided by cellular network. Sending large latin encoded messages work on smppsim. Smppsim fails to process any ucs encoded messages. I read up on it and came across these at http://www.activexperts.com/sms-component/smpp-specifications/smpp-parameter-definition/ :
short_message
The short_message parameter contains the user data. A maximum of 254 octets can be sent. ESME's should use the optional message_payload parameter in submit_sm, submit_multi, and deliver_sm to send larger user data sizes.
sm_length
The sm_length parameter specifies the length of the short_message parameter in octets. The sm_length should be set to 0 in the submit_sm, submit_multi, and deliver_sm PDUs if the message_payload parameter is being used to send user data larger than 254 octets.
If above is right, can this library support sending larger than 160 chars messages? I couldn't find any logic to handle this in code.
Not able to set the dynamic listening IP and port. Throwing error mentioning,s.l cannot be set.
Can I use tx.Submit in thread ? I can see in the example_test it is used inside http Handler function
Also if I use tx.Submit in 10 threads, the delivery receipts traffic would increase. Will the Handler function of Transceiver perform fast enough ?
Hi,
Please, if you could give a simple sample - to check to connect a client(s))? (need to check every 30 sec, if a client doesn't send any data - his need disconnect)
Thanks!
Hi,
With the latest version sms receive event is not firing and status is changing continuously connected and disconnects. Message send successfully but received message event is not firing. When using Transmitter in place of Transceiver without handler then status connected for all time.
Using below code .
f := func(p pdu.Body) {
switch p.Header().ID {
case pdu.DeliverSMID:
f := p.Fields()
src := f[pdufield.SourceAddr]
dst := f[pdufield.DestinationAddr]
txt := f[pdufield.ShortMessage]
log.Printf("Short message from=%q to=%q: %q",
src, dst, txt)
}
}
tx := &smpp.Transceiver{
Addr: "192.168.0.103:8802",
User: "userid",
Passwd: "password",
Handler: f, // Handle incoming SM or delivery receipts.
}
// Create persistent connection, wait for the first status.
conn := <-tx.Bind()
if conn.Status() != smpp.Connected {
log.Fatal(conn.Error())
}
sm, err := tx.Submit(&smpp.ShortMessage{
Src: "src",
Dst: "des",
Text: pdutext.Raw("sandeep"),
Register: pdufield.NoDeliveryReceipt,
})
if err != nil {
log.Fatal(err)
}
log.Println("Message ID:", sm.RespID())
for{
time.Sleep(time.Millisecond * 1600)
}
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.