From af18c7aea86ec48c53bdf2e4a3ec54193a71d29a Mon Sep 17 00:00:00 2001 From: Bernhard B Date: Thu, 5 Mar 2026 20:41:17 +0100 Subject: [PATCH] switched to signal-cli daemon mode * this gets rid off the ugly netcat workaround and should improve the general stability of the connection to the signal-cli binary in json-rpc mode. --- src/client/client.go | 4 ++-- src/client/jsonrpc2.go | 37 ++++++++++++++++++++++++---------- src/main.go | 2 +- src/scripts/jsonrpc2-helper.go | 4 ++-- 4 files changed, 31 insertions(+), 16 deletions(-) diff --git a/src/client/client.go b/src/client/client.go index d1cc396..dcd6b48 100644 --- a/src/client/client.go +++ b/src/client/client.go @@ -410,7 +410,7 @@ func (s *SignalClient) GetSignalCliMode() SignalCliMode { return s.signalCliMode } -func (s *SignalClient) Init() error { +func (s *SignalClient) Init(maxRetries int) error { s.signalCliApiConfig = utils.NewSignalCliApiConfig() err := s.signalCliApiConfig.Load(s.signalCliApiConfigPath) if err != nil { @@ -427,7 +427,7 @@ func (s *SignalClient) Init() error { tcpPortsNumberMapping := s.jsonRpc2ClientConfig.GetTcpPortsForNumbers() for number, tcpPort := range tcpPortsNumberMapping { s.jsonRpc2Clients[number] = NewJsonRpc2Client(s.signalCliApiConfig, number) - err := s.jsonRpc2Clients[number].Dial("127.0.0.1:" + strconv.FormatInt(tcpPort, 10)) + err := s.jsonRpc2Clients[number].Dial("127.0.0.1:"+strconv.FormatInt(tcpPort, 10), maxRetries) if err != nil { return err } diff --git a/src/client/jsonrpc2.go b/src/client/jsonrpc2.go index b2fae23..00eaa09 100644 --- a/src/client/jsonrpc2.go +++ b/src/client/jsonrpc2.go @@ -2,14 +2,14 @@ package client import ( "bufio" + "bytes" "encoding/json" "errors" "net" + "net/http" + "strconv" "sync" "time" - "net/http" - "bytes" - "strconv" "github.com/bbernhard/signal-cli-rest-api/utils" uuid "github.com/gofrs/uuid" @@ -60,11 +60,12 @@ type JsonRpc2Client struct { conn net.Conn receivedResponsesById map[string]chan JsonRpc2MessageResponse receivedMessagesChannels map[string]chan JsonRpc2ReceivedMessage - lastTimeErrorMessageSent time.Time - signalCliApiConfig *utils.SignalCliApiConfig - number string - receivedMessagesMutex sync.Mutex - receivedResponsesMutex sync.Mutex + //lastTimeErrorMessageSent time.Time + signalCliApiConfig *utils.SignalCliApiConfig + number string + receivedMessagesMutex sync.Mutex + receivedResponsesMutex sync.Mutex + address string } func NewJsonRpc2Client(signalCliApiConfig *utils.SignalCliApiConfig, number string) *JsonRpc2Client { @@ -76,10 +77,24 @@ func NewJsonRpc2Client(signalCliApiConfig *utils.SignalCliApiConfig, number stri } } -func (r *JsonRpc2Client) Dial(address string) error { +func (r *JsonRpc2Client) Dial(address string, maxRetries int) error { var err error - r.conn, err = net.Dial("tcp", address) - if err != nil { + r.address = address + connected := false + for i := 0; i < maxRetries; i++ { + r.conn, err = net.Dial("tcp", address) + if err != nil { + log.Info("Waiting for signal-cli to start up in daemon mode...") + time.Sleep(2 * time.Second) + continue + } + + connected = true + log.Info("Successfully connected to signal-cli in daemon mode") + break + } + + if !connected { return err } diff --git a/src/main.go b/src/main.go index 68ac19c..67f6bbe 100644 --- a/src/main.go +++ b/src/main.go @@ -163,7 +163,7 @@ func main() { jsonRpc2ClientConfigPathPath := *signalCliConfig + "/jsonrpc2.yml" signalCliApiConfigPath := *signalCliConfig + "/api-config.yml" signalClient := client.NewSignalClient(*signalCliConfig, *attachmentTmpDir, *avatarTmpDir, signalCliMode, jsonRpc2ClientConfigPathPath, signalCliApiConfigPath, webhookUrl) - err = signalClient.Init() + err = signalClient.Init(15) if err != nil { log.Fatal("Couldn't init Signal Client: ", err.Error()) } diff --git a/src/scripts/jsonrpc2-helper.go b/src/scripts/jsonrpc2-helper.go index a7bbc5d..829f089 100644 --- a/src/scripts/jsonrpc2-helper.go +++ b/src/scripts/jsonrpc2-helper.go @@ -14,7 +14,7 @@ import ( const supervisorctlConfigTemplate = ` [program:%s] process_name=%s -command=bash -c "nc -l -p %d <%s | signal-cli --output=json --config %s%s jsonRpc%s%s >%s" +command=signal-cli --output=json --config %s%s daemon %s%s --tcp 127.0.0.1:%d autostart=true autorestart=true startretries=10 @@ -96,7 +96,7 @@ func main() { supervisorctlConfigFilename := "/etc/supervisor/conf.d/" + "signal-cli-json-rpc-1.conf" supervisorctlConfig := fmt.Sprintf(supervisorctlConfigTemplate, supervisorctlProgramName, supervisorctlProgramName, - tcpPort, fifoPathname, signalCliConfigDir, trustNewIdentities, signalCliIgnoreAttachments, signalCliIgnoreStories, fifoPathname, + signalCliConfigDir, trustNewIdentities, signalCliIgnoreAttachments, signalCliIgnoreStories, tcpPort, supervisorctlProgramName, supervisorctlProgramName) err = ioutil.WriteFile(supervisorctlConfigFilename, []byte(supervisorctlConfig), 0644)