Git Product home page Git Product logo

fsock's Introduction

FreeSWITCH socket client written in Go

Installation

go get github.com/cgrates/fsock

Support

Join CGRateS on Google Groups here.

License

fsock.go is released under the MIT License. Copyright (C) ITsysCOM GmbH. All Rights Reserved.

Sample usage code

package main

import (
	"fmt"
	"log/syslog"

	"github.com/cgrates/fsock"
)

// Formats the event as map and prints it out
func printHeartbeat(eventStr string, connIdx int) {
	// Format the event from string into Go's map type
	eventMap := fsock.FSEventStrToMap(eventStr, []string{})
	fmt.Printf("%v, connIdx: %d\n", eventMap, connIdx)
}

// Formats the event as map and prints it out
func printChannelAnswer(eventStr string, connIdx int) {
	// Format the event from string into Go's map type
	eventMap := fsock.FSEventStrToMap(eventStr, []string{})
	fmt.Printf("%v, connIdx: %d\n", eventMap, connIdx)
}

// Formats the event as map and prints it out
func printChannelHangup(eventStr string, connIdx int) {
	// Format the event from string into Go's map type
	eventMap := fsock.FSEventStrToMap(eventStr, []string{})
	fmt.Printf("%v, connIdx: %d\n", eventMap, connIdx)
}

func main() {
	// Init a syslog writter for our test
	l, errLog := syslog.New(syslog.LOG_INFO, "TestFSock")
	if errLog != nil {
		l.Crit(fmt.Sprintf("Cannot connect to syslog:", errLog))
		return
	}

	// Filters
	evFilters := make(map[string][]string)
	evFilters["Event-Name"] = append(evFilters["Event-Name"], "CHANNEL_ANSWER")
	evFilters["Event-Name"] = append(evFilters["Event-Name"], "CHANNEL_HANGUP_COMPLETE")

	// We are interested in heartbeats, channel_answer, channel_hangup define handler for them
	evHandlers := map[string][]func(string, int){
		"HEARTBEAT":               {printHeartbeat},
		"CHANNEL_ANSWER":          {printChannelAnswer},
		"CHANNEL_HANGUP_COMPLETE": {printChannelHangup},
	}
	errChan := make(chan error)
	fs, err := fsock.NewFSock("127.0.0.1:8021", "ClueCon", 10, evHandlers, evFilters, l, 0, false, errChan)
	if err != nil {
		l.Crit(fmt.Sprintf("FreeSWITCH error:", err))
		return
	}
	<- errChan

}

fsock's People

Contributors

bhepp avatar cgrates avatar codelingobot avatar danbogos avatar gezimbll avatar ionutboangiu avatar pechenn avatar praveenchourasia avatar rif avatar tlparrott avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

fsock's Issues

Does not read buffer correctly on slower connections.

Sometimes when I connect to remote FreeSWITCH server I get this error

Unexpected filter-events reply received: <Content-Length: 1023 Content-Type: text/event-plain

From what I've seen in the code it might be that the readHeaders is not waiting enought time to receive a complete response and then these responses get returned later for subsequent commands (like CallAPI)

Possible concurrent issue

I have a problem with the library.
I think I know where it could come from.

The library is built with this schema :
1 - Lock conn
2 - Send command/event to socket
3 - Unlock conn
4 - Read channel apiChan/cmdChan to get response

With heavy load of commands, you can see that you can read from channel another response of another comand, since the unlock is before the reading part.

What do you think?

cgrates/fsock: Issue with evfilters (Support to handle multiple Event values in the same Filter)

FreeSWITCH expects filter command in the format:

filter <EventHeader> <ValueToFilter> 
e.g. filter Event-Name CHANNEL_EXECUTE

As per fsock.NewFSock() prototype eventFilters type is map[string]string

func NewFSock(fsaddr, fspaswd string, reconnects int, eventHandlers map[string][]func(string, string), eventFilters map[string]string, l *syslog.Writer, connId string) (*FSock, error) {

Later in the code when filters are enabled in the function filterEvents() the filter command is build using

for hdr, val := range filters {
 cmd := "filter " + hdr + " " + val + "\n\n"

Due to eventHandlers being declared as map[string]string, multiple filter commands with same events can't be created (as it breaks the unique key criteria). For instance this fails:

evFilters := map[string]string {
"Event-Name": "CHANNEL_EXECUTE",
"Event-Name": "CHANNEL_HANGUP",
}

Support should be added to handle multiple Event values in the same filter.

nil pointer panics handling bgapi requests

We started getting nil pointer panics related with fsock and syslog calls and got it down to this piece of code that seems to log something when handling bgapi requests. We're initializing with the NewFsock function with nil value for the sysloger argument.

func (self *FSock) doBackgroudJob(event string) { // add mutex protection
   evMap := EventToMap(event)
   jobUuid, has := evMap["Job-UUID"]
   if !has {
        self.logger.Err("<FSock> BACKGROUND_JOB with no Job-UUID")
        return
   }
...

We noticed that elsewhere, whenever self.logger.Err is called it's guarded by something like "if self.logger != nil".

Possible concurrency issue - events not being executed sequentially.

Hi Dan,
This is the part which I'm going to challenge :-)

for _, handlerFunc := range self.eventHandlers[handleName] { go handlerFunc(event, self.connId) }

We've just had an issue when events are not being processed sequentially.
I's probably regarding to every handlerFunc being executed as a separate goroutine. From the library point of view, it makes perfectly sense. You can't block here - you want to process next event as soon as possible. Things get complicated when you need different time period to process events.
In out case we have spotted that library executes conference:del-member was fired before add-member.
When you want to build some kind of state machine it gets very messy.
What we did, we removed 'go' from the library but we are executing code as goroutine inside the handler function. If we require some events to be processed sequentially we can still do it.

What do you think? Did you have this issue in cgrates? can you afford to call every handler as goroutine?

greetings from Nexmo :-)
Cezary

Error starting example from README

Error starting example from README:

cannot use evHandlers (type map[string][]func(string, string)) as type map[string][]func(string, int) in argument to fsock.NewFSock

cannot use "wetsfnmretiewrtpj" (type string) as type int in argument to fsock.NewFSock

The code:
    evHandlers := map[string][]func(string, string){
	    "HEARTBEAT":               {printHeartbeat},
	    "CHANNEL_ANSWER":          {printChannelAnswer},
	    "CHANNEL_HANGUP_COMPLETE": {printChannelHangup},
    }

    fs, err := fsock.NewFSock("127.0.0.1:8021", "ClueCon", 10, evHandlers, evFilters, l, "wetsfnmretiewrtpj")

problem parsing fs cvs

isGroup, _ := regexp.MatchString("{.*}|[.*]", spltData)
isPrevGroup, _ := regexp.MatchString("{.*}|[.*]", retSplit[idx-1])

Should we escape the brackets?

Why does SendApiCmd return header and body concatenated

Hi,

When using SendApiCmd function, the response is the API headers plus the actual response body combined.

This occurs here:

https://github.com/cgrates/fsock/blob/master/fsock.go#L329

Would it be possible to delimit the hdr from the body (either by changing the type of the channel to send a struct containing header and body properties) or by putting a delimiter character of some sort.

It would be most useful to have the SendApiCmd only return the body of the response, which could be modified to detect errors in the header, but still only return the body.

Support for bgapi

I've tried the general "SendCmd" for that, but it blocks infinitely when used in combination with "bgapi".
The example string I send was:
bgapi originate loopback/answer,/ib_connect ib_connect

Sending this string via telnet session works correctly and the FS response is:
Content-Type: command/reply
Reply-Text: +OK Job-UUID: f531c865-7005-4253-8d26-9b675798db0f
Job-UUID: f531c865-7005-4253-8d26-9b675798db0f

Somehow fsock does not get the response and blocks forever.

Using SendMsgCmd from multiple Go routines concurrently

Hi,

I'm not sure if this an issue or not, more of a discussion.

If register an event handler that is called multiple times concurrently (for example from multiple calls) and that event requires that I generate a 'response' back to Freeswitch using the SendMsgCmd() function.

My event handlers have access to the FSock pointer variable, so can call SendMsgCmd() from inside their event handler Go routine.

If multiple Go routines call SendMsgCmd() at the same time, do the response get muddled, or does SendMsgCmd() lock self.conn before writing to it?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.