func (context *Context) Broadcast(eventName string, params interface{}, groups ...string) {
	newContext := context.ChildEventContext(eventName, payload.New(params), groups, true)
	context.broker.BroadcastEvent(newContext)
}
Broadcast : Broadcast an event for all local & remote services
package context
import (
	"errors"
	"fmt"
	"github.com/moleculer-go/moleculer"
	"github.com/moleculer-go/moleculer/payload"
	"github.com/moleculer-go/moleculer/util"
	log "github.com/sirupsen/logrus"
)
type Context struct {
	id           string
	requestID    string
	broker       *moleculer.BrokerDelegates
	targetNodeID string
	sourceNodeID string
	parentID     string
	actionName   string
	eventName    string
	groups       []string
	broadcast    bool
	params       moleculer.Payload
	meta         moleculer.Payload
	timeout      int
	level        int
	caller       string
}
func BrokerContext(broker *moleculer.BrokerDelegates) moleculer.BrokerContext {
	localNodeID := broker.LocalNode().GetID()
	id := fmt.Sprint("rootContext-broker-", localNodeID, "-", util.RandomString(12))
	context := Context{
		id:       id,
		broker:   broker,
		level:    1,
		parentID: "ImGroot;)",
		meta:     payload.Empty(),
	}
	return &context
}
func (context *Context) ChildEventContext(eventName string, params moleculer.Payload, groups []string, broadcast bool) moleculer.BrokerContext {
	parentContext := context
	meta := parentContext.meta
	if context.broker.Config.Metrics {
		meta = meta.Add("tracing", true)
	}
	id := util.RandomString(12)
	var requestID string
	if parentContext.requestID != "" {
		requestID = parentContext.requestID
	} else {
		requestID = id
	}
	caller := parentContext.actionName
	if parentContext.eventName != "" {
		caller = parentContext.eventName
	}
	eventContext := Context{
		id:        id,
		requestID: requestID,
		broker:    parentContext.broker,
		eventName: eventName,
		groups:    groups,
		params:    params,
		broadcast: broadcast,
		level:     parentContext.level + 1,
		meta:      meta,
		parentID:  parentContext.id,
		caller:    caller,
	}
	return &eventContext
}
func (context *Context) BrokerDelegates() *moleculer.BrokerDelegates {
	return context.broker
}
func (context *Context) ChildActionContext(actionName string, params moleculer.Payload, opts ...moleculer.Options) moleculer.BrokerContext {
	parentContext := context
	meta := parentContext.meta
	if context.broker.Config.Metrics {
		meta = meta.Add("tracing", true)
	}
	if len(opts) > 0 && opts[0].Meta != nil && opts[0].Meta.Len() > 0 {
		meta = meta.AddMany(opts[0].Meta.RawMap())
	}
	id := util.RandomString(12)
	var requestID string
	if parentContext.requestID != "" {
		requestID = parentContext.requestID
	} else {
		requestID = id
	}
	caller := parentContext.actionName
	if parentContext.eventName != "" {
		caller = parentContext.eventName
	}
	actionContext := Context{
		id:         id,
		requestID:  requestID,
		broker:     parentContext.broker,
		actionName: actionName,
		params:     params,
		level:      parentContext.level + 1,
		meta:       meta,
		parentID:   parentContext.id,
		caller:     caller,
	}
	return &actionContext
}
func ActionContext(broker *moleculer.BrokerDelegates, values map[string]interface{}) moleculer.BrokerContext {
	var level int
	var timeout int
	var meta moleculer.Payload
	sourceNodeID := values["sender"].(string)
	id := values["id"].(string)
	actionName, isAction := values["action"]
	if !isAction {
		panic(errors.New("Can't create an action context, you need a action field!"))
	}
	level = values["level"].(int)
	parentID := ""
	if p, ok := values["parentID"]; ok {
		if s, ok := p.(string); ok {
			parentID = s
		}
	}
	params := payload.New(values["params"])
	if values["timeout"] != nil {
		timeout = values["timeout"].(int)
	}
	if values["meta"] != nil {
		meta = payload.New(values["meta"])
	} else {
		meta = payload.Empty()
	}
	newContext := Context{
		broker:       broker,
		sourceNodeID: sourceNodeID,
		targetNodeID: sourceNodeID,
		id:           id,
		actionName:   actionName.(string),
		parentID:     parentID,
		params:       params,
		meta:         meta,
		timeout:      timeout,
		level:        level,
	}
	return &newContext
}
func EventContext(broker *moleculer.BrokerDelegates, values map[string]interface{}) moleculer.BrokerContext {
	var meta moleculer.Payload
	sourceNodeID := values["sender"].(string)
	id := ""
	if t, ok := values["id"]; ok {
		id = t.(string)
	}
	eventName, isEvent := values["event"]
	if !isEvent {
		panic(errors.New("Can't create an event context, you need an event field!"))
	}
	if values["meta"] != nil {
		meta = payload.New(values["meta"])
	} else {
		meta = payload.Empty()
	}
	newContext := Context{
		broker:       broker,
		sourceNodeID: sourceNodeID,
		id:           id,
		eventName:    eventName.(string),
		broadcast:    values["broadcast"].(bool),
		params:       payload.New(values["data"]),
		meta:         meta,
	}
	if values["groups"] != nil {
		temp := values["groups"]
		aTransformer := payload.ArrayTransformer(&temp)
		if aTransformer != nil {
			iArray := aTransformer.InterfaceArray(&temp)
			sGroups := make([]string, len(iArray))
			for index, item := range iArray {
				sGroups[index] = item.(string)
			}
			newContext.groups = sGroups
		}
	}
	return &newContext
}
func (context *Context) IsBroadcast() bool {
	return context.broadcast
}
func (context *Context) RequestID() string {
	return context.requestID
}
func (context *Context) AsMap() map[string]interface{} {
	mapResult := make(map[string]interface{})
	var tracing bool
	if context.meta.Get("tracing").Exists() {
		tracing = context.meta.Get("tracing").Bool()
	}
	mapResult["id"] = context.id
	mapResult["requestID"] = context.requestID
	mapResult["level"] = context.level
	mapResult["meta"] = context.meta.RawMap()
	mapResult["caller"] = context.caller
	mapResult["tracing"] = tracing
	mapResult["parentID"] = context.parentID
	if context.actionName != "" {
		mapResult["action"] = context.actionName
		mapResult["timeout"] = context.timeout
		mapResult["params"] = context.params.Value()
	}
	if context.eventName != "" {
		mapResult["event"] = context.eventName
		mapResult["groups"] = context.groups
		mapResult["broadcast"] = context.broadcast
		mapResult["data"] = context.params.Value()
		mapResult["level"] = context.level
	}
	mapResult["stream"] = false
	return mapResult
}
func (context *Context) MCall(callMaps map[string]map[string]interface{}) chan map[string]moleculer.Payload {
	return context.broker.MultActionDelegate(callMaps)
}
func (context *Context) Call(actionName string, params interface{}, opts ...moleculer.Options) chan moleculer.Payload {
	actionContext := context.ChildActionContext(actionName, payload.New(params), opts...)
	return context.broker.ActionDelegate(actionContext, opts...)
}
func (context *Context) Emit(eventName string, params interface{}, groups ...string) {
	context.Logger().Debug("Context Emit() eventName: ", eventName)
	newContext := context.ChildEventContext(eventName, payload.New(params), groups, false)
	context.broker.EmitEvent(newContext)
}