aboutsummaryrefslogblamecommitdiff
path: root/test_msgnet/main.go
blob: 0da5af7e7bbaf2a733ced814552aa2b5911949da (plain) (tree)
1
2
3
4
5
6
7
8
            



                                                  


                                                             


          

                     
            









                                             
                      














                                                                 

                             
                                                               





















                                                                       
                       
                                                                                                 

                                            

                        
                         








                                                             
                     
                                                                                           
                                            

                        
                         




                                             
                    
                                                                                         
                                            

                        
                         
































                                                                       


                                 


                                                                                                   
 


                                                                                                 












                                
                                                                               
                                 
                                                                                









                                   
package main

// #cgo CFLAGS: -I${SRCDIR}/../salticidae/include/
// #include "salticidae/network.h"
// void onTerm(int sig);
// void onReceiveHello(msg_t *, msgnetwork_conn_t *, void *);
// void onReceiveAck(msg_t *, msgnetwork_conn_t *, void *);
// void connHandler(msgnetwork_conn_t *, bool, void *);
import "C"

import (
    "encoding/binary"
    "fmt"
    "unsafe"
    "salticidae-go"
)

var ec salticidae.EventContext
const (
    MSG_OPCODE_HELLO salticidae.Opcode = iota
    MSG_OPCODE_ACK
)

//export onTerm
func onTerm(_ C.int) {
    ec.Stop()
}

type MsgHello struct {
    name string
    text string
}

func msgHelloSerialize(name string, text string) salticidae.Msg {
    serialized := salticidae.NewDataStream()
    t := make([]byte, 4)
    binary.LittleEndian.PutUint32(t, uint32(len(name)))
    serialized.PutData(t)
    serialized.PutData([]byte(name))
    serialized.PutData([]byte(text))
    return salticidae.NewMsg(
        MSG_OPCODE_HELLO,
        salticidae.NewByteArrayMovedFromDataStream(serialized))
}

func msgHelloUnserialize(msg salticidae.Msg) MsgHello {
    p := msg.GetPayload()
    length := binary.LittleEndian.Uint32(p.GetData(4))
    name := string(p.GetData(int(length)))
    text := string(p.GetData(p.Size()))
    p.Free()
    return MsgHello { name: name, text: text }
}

func msgAckSerialize() salticidae.Msg {
    return salticidae.NewMsg(MSG_OPCODE_ACK, salticidae.NewByteArray())
}

type MyNet struct {
    net salticidae.MsgNetwork
    name string
}

var alice, bob MyNet

//export onReceiveHello
func onReceiveHello(__msg *C.struct_msg_t, _conn *C.struct_msgnetwork_conn_t, _ unsafe.Pointer) {
    _msg := salticidae.Msg(__msg)
    conn := salticidae.MsgNetworkConn(_conn)
    net := conn.GetNet()
    name := bob.name
    if net == alice.net {
        name = alice.name
    }
    msg := msgHelloUnserialize(_msg)
    fmt.Printf("[%s] %s says %s\n", name, msg.name, msg.text)
    ack := msgAckSerialize()
    net.SendMsg(ack, conn)
    ack.Free()
}

//export onReceiveAck
func onReceiveAck(_ *C.struct_msg_t, _conn *C.struct_msgnetwork_conn_t, _ unsafe.Pointer) {
    conn := salticidae.MsgNetworkConn(_conn)
    net := conn.GetNet()
    name := bob.name
    if net == alice.net {
        name = alice.name
    }
    fmt.Printf("[%s] the peer knows\n", name)
}

//export connHandler
func connHandler(_conn *C.struct_msgnetwork_conn_t, connected C.bool, _ unsafe.Pointer) {
    conn := salticidae.MsgNetworkConn(_conn)
    net := conn.GetNet()
    n := &bob
    if net == alice.net {
        n = &alice
    }
    name := n.name
    if connected {
        if conn.GetMode() == salticidae.CONN_MODE_ACTIVE {
            fmt.Printf("[%s] Connected, sending hello.", name)
            hello := msgHelloSerialize(name, "Hello there!")
            n.net.SendMsg(hello, conn)
            hello.Free()
        } else {
            fmt.Printf("[%s] Accepted, waiting for greetings.\n", name)
        }
    } else {
        fmt.Printf("[%s] Disconnected, retrying.\n", name)
        net.Connect(conn.GetAddr())
    }
}

func genMyNet(ec salticidae.EventContext, name string) MyNet {
    netconfig := salticidae.NewMsgNetworkConfig()
    n := MyNet {
        net: salticidae.NewMsgNetwork(ec, netconfig),
        name: name,
    }
    netconfig.Free()
    return n
}

func main() {
    ec = salticidae.NewEventContext()
    alice_addr := salticidae.NewAddrFromIPPortString("127.0.0.1:12345")
    bob_addr := salticidae.NewAddrFromIPPortString("127.0.0.1:12346")

    alice = genMyNet(ec, "Alice")
    bob = genMyNet(ec, "Bob")

    alice.net.RegHandler(MSG_OPCODE_HELLO, salticidae.MsgNetworkMsgCallback(C.onReceiveHello), nil)
    alice.net.RegHandler(MSG_OPCODE_ACK, salticidae.MsgNetworkMsgCallback(C.onReceiveAck), nil)
    alice.net.RegConnHandler(salticidae.MsgNetworkConnCallback(C.connHandler), nil)

    bob.net.RegHandler(MSG_OPCODE_HELLO, salticidae.MsgNetworkMsgCallback(C.onReceiveHello), nil)
    bob.net.RegHandler(MSG_OPCODE_ACK, salticidae.MsgNetworkMsgCallback(C.onReceiveAck), nil)
    bob.net.RegConnHandler(salticidae.MsgNetworkConnCallback(C.connHandler), nil)

    alice.net.Start()
    bob.net.Start()

    alice.net.Listen(alice_addr)
    bob.net.Listen(bob_addr)

    alice.net.Connect(bob_addr)
    bob.net.Connect(alice_addr)

    alice_addr.Free()
    bob_addr.Free()

    ev_int := salticidae.NewSigEvent(ec, salticidae.SigEventCallback(C.onTerm))
    ev_int.Add(salticidae.SIGINT)
    ev_term := salticidae.NewSigEvent(ec, salticidae.SigEventCallback(C.onTerm))
    ev_term.Add(salticidae.SIGTERM)

    ec.Dispatch()

    ev_int.Free()
    ev_term.Free()
    alice.net.Free()
    bob.net.Free()
    ec.Free()
}