Giter VIP home page Giter VIP logo

hprose-golang's Introduction

HPROSE is short for High Performance Remote Object Service Engine.

It is a modern, lightweight, cross-language, cross-platform, object-oriented, high performance, remote dynamic communication middleware. It is not only easy to use, but powerful. You just need a little time to learn, then you can use it to easily construct cross language cross platform distributed application system.

It contains a semi-text serialization format, an RPC protocol and its implementation. The meaning of semi-text is all the data are represented as text, except the original binary data. The serialization format is very compact. It takes up very little space, and can be parsed very quickly in programming language. You can use this serialization format without hprose RPC protocol in other communications protocols, data storage, and more. If you want to know more, please read Hprose Specification.

Join the chat at https://gitter.im/hprose/hprose

hprose-golang's People

Contributors

andot 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  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  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  avatar  avatar  avatar

hprose-golang's Issues

how can call javascript client function on server golang

hi .i see all example for find example for JavaScript client and golang server bi-directional.how i must implement a server in golang and client in (browser firefox) JavaScript and then call JavaScript function from server over websocket?

note : i use beego

服务器是java 客户端是go 调用无效

服务器

package RPCServer;

import hprose.server.HproseTcpServer;

import java.io.IOException;
import java.net.URISyntaxException;

public class RPCServer {
    public static String hello() {
        return "Hello boy";
    }

    public static void main(String[] args) throws URISyntaxException, IOException {
        HproseTcpServer server = new HproseTcpServer("tcp://127.0.0.1:8888");
        server.add("hello", RPCServer.class);
        server.start();
        System.out.println("START tcp");
        System.in.read();
        server.stop();
        System.out.println("STOP");
    }
}

客户端

package main

import (
	"fmt"

	"github.com/hprose/hprose-golang/rpc"
)

type RPCServer struct {
	hello func() string
}

func main() {
	client := rpc.NewClient("tcp://127.0.0.1:8888")
	fmt.Println(client.URI())
	var test *RPCServer
	client.UseService(&test)
	fmt.Println(test)
}

结果就是客户端useService test指针一直是nil

how do you pass the client's IP into the method of publishing?

如何将将客户端的ip传入发布的方法中,

example

package main

import (
	"github.com/hprose/hprose-golang/rpc"
	"net/http"
)

type Member struct{}

type Login struct {
	Username string
	Password string
}

type LoginRsp struct {
	Status bool
	Token  string
}

func (m *Member) Login(req *Login, rsp *LoginRsp, context *rpc.HTTPContext) error {
	// How to get the client IP?
	return nil
}

func (m *Member) Regiest(req *Login, rsp *LoginRsp) error {
	// How to get the client IP?
	return nil
}

func main() {
	service := rpc.NewHTTPService()
	service.AddNetRPCMethods(new(Member))
	http.ListenAndServe(":8080", service)
}

hprose-go 远程调用性能有待优化

在ThinkPad W540 8Core超线程,32G 内存机器上测试,使用样例代码进行测试,更改代码如下:

type Stub struct {
    Hello func(string) (string, error)
}

func main() {
    runtime.GOMAXPROCS(runtime.NumCPU())
    client := hprose.NewClient("tcp4://127.0.0.1:4321/")
    var stub *Stub
    client.UseService(&stub)
    client.SetKeepAlive(true)
    startTime := time.Now()
    for i :=1; i < 1000000; i++ {
        stub.Hello("world")
    }
    endTime := time.Now()
    fmt.Println("Time used: ", endTime.Sub(startTime).Seconds())

    result, error := stub.Hello("world")
    if error == nil {
        fmt.Println(result)
    } else {
        fmt.Println(error)
    }
}

经过多次测试,CPU使用率极低只有10%不到,100万次调用平均花时 55秒左右,也就是每秒不到2万次调用,性能有待优化!

这种简单的Hello测试,按理能达到50万次调用每秒以上。

参数传输性能较低

// hps_001 project main.go
package main

import (
"github.com/hprose/hprose-go"
)

func WriteParas(paras []int) int {
return 1
}

func main() {
service := hprose.NewTcpServer("tcp://127.0.0.1:2212")
service.AddFunction("WriteParas", WriteParas)
service.Start()
}

// hpc_001 project main.go
package main

import (
"fmt"
"github.com/hprose/hprose-go"
"time"
)

type Stub struct {
WriteParas func([]int) int
}

func main() {
client := hprose.NewTcpClient("tcp://127.0.0.1:2212")

var ro *Stub
client.UseService(&ro)
paras := make([]int, 10000000)

for {
    startTm := time.Now().UnixNano()

    ro.WriteParas(paras)

    endTm := time.Now().UnixNano()

    fmt.Println("use time ", float64(endTm-startTm)/1000000.0, " ms")
}

}

在windows 7 64bit, go 1.5.1,硬件配置thinkpad t430s上运行,每次调用要
use time 555.0317 ms
use time 535.0306 ms
use time 546.0313 ms
use time 541.0309 ms
use time 547.0313 ms
处理效率较低

服务端断线的异常处理

碰到一种情况就是在运行过程中,服务端因为某些原因断线了。与此同时客户端在向服务端传输信息。由于服务端断线了。导致客户端一起挂了。这样的情况应该如何处理。

新版经常出现服务崩溃

Signal 1606415768
fatal error: unexpected signal during runtime execution
panic during panic
[signal SIGSEGV: segmentation violation code=0x1 addr=0x1177a9 pc=0x40401e9]

runtime stack:
runtime.startpanic_m()
/usr/local/go/src/runtime/panic.go:623 +0xfc
runtime.systemstack(0x46031f0)
/usr/local/go/src/runtime/asm_amd64.s:314 +0xab
runtime.startpanic()
/usr/local/go/src/runtime/panic.go:544 +0x1e
runtime.throw(0x45d680e, 0x2a)
/usr/local/go/src/runtime/panic.go:565 +0x88
runtime.sigpanic()
/usr/local/go/src/runtime/sigpanic_unix.go:12 +0x2cc
runtime.sighandler(0x7fff5fbff598, 0x46b2ed6, 0x117779, 0x117779)
/usr/local/go/src/runtime/signal_amd64x.go:167 +0x489

goroutine 1 [chan receive, 109 minutes]:
github.com/hprose/hprose-golang/rpc.(*starter).Start(0xc42056e190, 0x45c907e, 0xd)
/Users/justinh/Development/Workspace/Golang_Path/src/github.com/hprose/hprose-golang/rpc/server.go:52 +0x2eb

goroutine 17 [syscall, 109 minutes, locked to thread]:
runtime.goexit()
/usr/local/go/src/runtime/asm_amd64.s:2086 +0x1

goroutine 19 [syscall, 109 minutes]:
os/signal.signal_recv(0x0)
/usr/local/go/src/runtime/sigqueue.go:116 +0x157
os/signal.loop()
/usr/local/go/src/os/signal/signal_unix.go:22 +0x22
created by os/signal.init.1
/usr/local/go/src/os/signal/signal_unix.go:28 +0x41

goroutine 20 [chan receive, 109 minutes]:
database/sql.(*DB).connectionOpener(0xc4200b6d10)
/usr/local/go/src/database/sql/sql.go:730 +0x4a
created by database/sql.Open
/usr/local/go/src/database/sql/sql.go:493 +0x1e9

goroutine 6 [IO wait]:
net.runtime_pollWait(0x5416740, 0x72, 0x1b)
/usr/local/go/src/runtime/netpoll.go:160 +0x59
net.(*pollDesc).wait(0xc420174060, 0x72, 0xc42004bbe8, 0xc4200740a0)
/usr/local/go/src/net/fd_poll_runtime.go:73 +0x38
net.(*pollDesc).waitRead(0xc420174060, 0x47db580, 0xc4200740a0)
/usr/local/go/src/net/fd_poll_runtime.go:78 +0x34
net.(*netFD).Read(0xc420174000, 0xc420592000, 0x1000, 0x1000, 0x0, 0x47db580, 0xc4200740a0)
/usr/local/go/src/net/fd_unix.go:243 +0x1a1
net.(*conn).Read(0xc42007e028, 0xc420592000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
/usr/local/go/src/net/net.go:173 +0x70
bufio.(*Reader).fill(0xc42002c180)
/usr/local/go/src/bufio/bufio.go:97 +0x10c
bufio.(*Reader).Read(0xc42002c180, 0xc4201581c1, 0x4, 0x4, 0x423a64a, 0xc42056e160, 0x0)
/usr/local/go/src/bufio/bufio.go:209 +0x1bc
io.ReadAtLeast(0x47d8e40, 0xc42002c180, 0xc4201581c1, 0x4, 0x4, 0x4, 0x2c, 0x0, 0x0)
/usr/local/go/src/io/io.go:307 +0xa4
github.com/hprose/hprose-golang/rpc.recvData(0x47d8e40, 0xc42002c180, 0xc4201581c0, 0xc4205ae120, 0x2c)
/Users/justinh/Development/Workspace/Golang_Path/src/github.com/hprose/hprose-golang/rpc/socket_common.go:90 +0x72
github.com/hprose/hprose-golang/rpc.(*connHandler).serve(0xc420158180, 0xc42056e000)
/Users/justinh/Development/Workspace/Golang_Path/src/github.com/hprose/hprose-golang/rpc/socket_service.go:160 +0xfe
github.com/hprose/hprose-golang/rpc.(*SocketService).serveConn(0xc42056e000, 0x47dff00, 0xc42007e028)
/Users/justinh/Development/Workspace/Golang_Path/src/github.com/hprose/hprose-golang/rpc/socket_service.go:99 +0x1e8
github.com/hprose/hprose-golang/rpc.(*TCPService).ServeTCPConn(0xc42056e000, 0xc42007e028)
/Users/justinh/Development/Workspace/Golang_Path/src/github.com/hprose/hprose-golang/rpc/tcp_service.go:67 +0x1b4
created by github.com/hprose/hprose-golang/rpc.(*TCPService).ServeTCP
/Users/justinh/Development/Workspace/Golang_Path/src/github.com/hprose/hprose-golang/rpc/tcp_service.go:93 +0xbc

hash of unhashable type

Create a hprose-go server like this:

type RandType struct {
        A string
}

func randType() interface{} {
        s := make([]RandType, 100)
        return s
}

func main() {
       service := hprose.NewHttpService()
       service.AddFunction("slice", randType)
       http.ListenAndServe(":9999", service)
}

An error occurs in js client Es62"runtime error: hash of unhashable type []RandType"z

I don't know what's happening inside hprose. So, could you help?

如何在OnBeforeInvoke中获取SocketContext?需要获取客户端的IP

...
func (e *ServerEvent) OnBeforeInvoke(name string, args []reflect.Value, byref bool, context rpc.Context) {
        // 这里如何获取IP?
	log.WithFields(logrus.Fields{
		"FuncName": name,
		"IP":       "",
	}).Info(args)
}

func main() {
	uri := "tcp4://127.0.0.1:10000"

	server := rpc.NewTCPServer(uri)
	server.AddFilter(StatFilter{"Server"})
	server.Event = &ServerEvent{}

	server.Start()
}
...

谢谢。

jsonrpc_client_filter 处理 map[string]interface{} 类型参数时的问题

Hi, 我有一个如下式样的方法.

type stub struct {
    IndexDoc  func(indexName, docId string, doc map[string]interface{}) error
}

在对 client 设置了 NewJSONRPCClientFilter("2.0") 之后, 调用始终报 no Hprose RPC request.
而不设置 json filter 的时候, 是可以正常调用.

我进行了一些调试, 发现处理过程中,
https://github.com/hprose/hprose-go/blob/master/hprose/jsonrpc_client_filter.go#L89
这里实际会报错: json: unsupported type: map[interface {}]interface {}, 导致 data 为空.

由此处向上回溯, 产生这个结果的相关代码如下:
https://github.com/hprose/hprose-go/blob/master/hprose/jsonrpc_client_filter.go#L81
https://github.com/hprose/hprose-go/blob/master/hprose/reader.go#L407
https://github.com/hprose/hprose-go/blob/master/hprose/reader.go#L1751

不知道这里是一个疏忽还是有意为之的结果?

我尝试了 byref 的方式, 但是在向服务圈发起请求之前就出现了一个
runtime error: index out of range
我还没有确认问题的原因.

where is baseclient id

i call to AddFunction like this

service.AddFunction("GetAll", models.GetAll)

and GetAll source code is here

func GetAll(t *rpc.WebSocketContext) map[string]*Object {
	t.Clients().Push("message", t.Clients().IDList("message"))
	return Objects
}

before return objects to client push other function in client named message

but when i use

t.Clients().Push("message", t.Clients().IDList("message"))

this means push message function on all client
i need just current client not all client
how i can detect current client id or how can access to baseclient from added function?

Go客户端的NewClient函数是否可以先建立连接,返回连接信息?

目前的通讯操作大部分都是长连接,所以还是需要一个类似于connect的连接服务接口函数,可以判断对于服务的连接状况,这样也便于下一步的数据操作。
现在的接口实现是要在具体接口函数调用时返回连接状态信息,使用较别扭,只能自己增加一个函数用于判断连接状况,能否在NewClient函数调用中就开始建立连接,并将连接放入连接池中,并将连接信息通过error返回?

byte_writer example won't build

Newer versions of go generate an error when trying to build a package that only contains test files, and due to the filename of the byte_writer example (byte_writer_test.go) go assumes this is a test and refuses to build it. The fix is to rename byte_writer_test.go => byte_writer.go.

有关消息订阅的代码问题

image
这个Subscribe方法里的第二个参数ID,应该是指Client的ID,这个参数是指本客户端能帮其他客户端订阅topic?我觉得应该客户端只能给自己订阅topic,不知道这个参数放在这里的使用场景是怎么样的? 是要这个客户端做管理节点?

golang服务端怎样返回list数据给PHP客户端使用,php怎么使用?

服务端(golang)

package main
type user struct {
    id uint32
    name string
    age byte
}

func getUsers(name string, age byte) []user {
    m := make([]user, 0)
    var u user
    u.id = 1000
    u.name = "tommy"
    u.age = 20
    m = append(m, u)
    u.id = 10001
    u.name = name
    u.age = age
    m = append(m, u)
    return m
}

func main() {
    server := rpc.NewTCPServer("tcp4://0.0.0.0:4321/")
    server.AddFunction("getUsers", getUsers)
    server.Start()
}

客户端(php)

<?php
require_once "vendor/autoload.php";

$client = new \Hprose\Socket\Client('tcp://127.0.0.1:4321', false);
$users = $client->getUsers('ikeeper', 26);
var_dump($users);

客户端打印出:

array(2) {
  [0]=>
  object(stdClass)#12 (0) {
  }
  [1]=>
  object(stdClass)#17 (0) {
  }
}

问题:php客户端获取不到数据

Access Http Header

Due to security reason, our communication need to put some authentication information in http header from hprose client and get it from hprose server.
But seems there is no way to access the header directly.
Any suggestions?
Thanks

HTTP client hangs if server is not present

Hello,
I have an issue when the HTTP server is off. The HTTP client try to connect, get a "connection refused error in sendAndReceive) and i get a panic with "invalid memory or address nil".

The first 10 times (the default number of max connection) I get this error (for me It's OK since my server is missing). The next times, It hangs (I suppose the pool of connection is empty (the previous crashed call are still alive ?)).

How can I fix this issue. Is this a bug a something missing in my code.

Regards.

Too many open files

当rpc客户端请求服务过快的时候,程序报句柄过多,已经修改了系统中ulimit 句柄的限制以及程序的ulimit限制,程序代码逻辑如下,句柄一直上涨,没有下降,

rpc server

package main

import (
	"fmt"
	"github.com/hprose/hprose-golang/rpc"
	"net/http"
)

type Data struct {
	Timestamp int64
	Content   string
}

type Rsp struct {
	Id     int64
	Status bool
}

func LogData(req *Data, context *rpc.HTTPContext) (rsp *Rsp) {
	ip := context.Request.RemoteAddr
	fmt.Println(ip)

	return &Rsp{
		Status: true,
		Id:     10,
	}
}

func ServerStatus() error {
	return nil
}

func main() {
	service := rpc.NewHTTPService()
	service.AddFunction("logdata", LogData)
	service.AddFunction("serverstatus", ServerStatus)
	http.ListenAndServe(":8080", service)
}

rpc client

package main

import (
	"fmt"
	"github.com/hprose/hprose-golang/rpc"
	"net/http"
	"time"
)

type Data struct {
	Timestamp int64
	Content   string
}

type Rsp struct {
	Id     int64
	Status bool
}

type Service struct {
	ServerStatus func() error
	LogData      func(request *Data) (response *Rsp)
}

// url 全路径
func UseService(url string) (service *Service, client *rpc.HTTPClient, err error) {
	defer func() {
		if err := recover(); err != nil {
			beego.Error("recover error", err)
		}
	}()

	client = rpc.NewHTTPClient(url)
	client.UseService(&service)
	err = service.ServerStatus()
	return service, client, err
}

func ServerLogData(url string, request *Data) *Rsp {
	service, client, err := UseService(url)
	if err != nil {
		client.Close()
		return nil
	}
	rsp := service.LogData(request)
	if rsp == nil {
		client.Close()
		return nil
	}
	client.Close()
	return rsp
}

func main() {
	request := &Data{
		Timestamp: time.Now().Unix(),
		Content:   "日志",
	}
	rsp := ServerLogData("http://127.0.0.1:8080", request)
	fmt.Println(rsp)
}

Why can work well without ClassManager.Register when use custom struct

// hps_001 project main.go
package main

import (
"github.com/hprose/hprose-go"
"net/http"
_ "reflect"
)

type FloatPara struct {
Id int32
Tag string
Desc string
Tm int32
}

type FloatData struct {
Id int32
Para []FloatPara
}

func getMeasList() FloatData {
return FloatData{22, []FloatPara{FloatPara{11, "float001", "desc_float001", 11111}, FloatPara{22, "float002", "desc_float002", 22222}}}
}

func main() {
//hprose.ClassManager.Register(reflect.TypeOf(FloatPara{}), "Para")
//hprose.ClassManager.Register(reflect.TypeOf(FloatData{}), "Data")

service := hprose.NewHttpService()
service.AddFunction("getMeasList", getMeasList)
http.ListenAndServe(":8080", service)

}

// hpc_001 project main.go
package main

import (
"fmt"
"github.com/hprose/hprose-go"
_"reflect"
)

type FloatPara struct {
Id int8
Tag string
Desc string
Tm int16
}

type FloatData struct {
Id int32
Para []FloatPara
}

type Stub struct {
GetMeasList func() FloatData
}

func main() {
//hprose.ClassManager.Register(reflect.TypeOf(FloatPara{}), "FloatPara")
//hprose.ClassManager.Register(reflect.TypeOf(FloatData{}), "FloatData")
client := hprose.NewClient("http://127.0.0.1:8080")

var ro *Stub
client.UseService(&ro)

aa := ro.GetMeasList()
fmt.Println(aa)

}

it can work well, why?

将创建连接放到调用方法之前?

如果配合服务发现的话, 一开始创建客户端的时候, 或者服务提供方down掉的时候, URIList是会为空的. 此时TCPClient就会报错, 如果可以将这个检测放到Invoke的时候的话, 这样会不会更方便一些呢?

这个逻辑我发现在其他版本里面(nodejs)也是一样的.

按照现有的逻辑, 似乎只能在每次 需要在每次调用方法的时候UseService一下?

No way to implement authorization

I'm trying to implement simple ip-based authorization, but it seems that it's impossible with current implementation of hprose-go - there is no access to the context from inside the exported function.

php作为hprose的server,想让golang作为client,server的函数参数为php的数组,golang中怎么传参呢

php作为hprose的server,想让golang作为client,server的函数参数为php的数组,golang中怎么传参呢。

下面是php有一个get的方法,只有一个参数,参数类型为php的数组。然后比如在其他语言的hprose,python中我传的一个dict,nodejs我传的对象,都是可以调用成功,但是在golang中不行,然后golang也刚刚开始学。懵了,弄了半天了,望指教,谢谢。

package main

import (
"fmt"
"github.com/hprose/hprose-golang/rpc"
)

type ApiService struct {
get func(map[string]string) (string, error)
}

func main(){
client := rpc.NewHTTPClient("xxx")
var api *ApiService
client.UseService(&api)
params := make(map[string]string)
params["api"] = "Session"
params["version"] = "master"
params["appkey"] = "xxx"
params["appsecret"] = "xxxx"
params["_sdk_lang"] = "hprose_golang"
result := api.get(params)
fmt.Printf("%v",result)
}

运行之后直接返回:
./test.go:22: multiple-value api.get() in single-value context

如何实现回调?希望给个例子

服务端:

func (myService) TestCallBack() (<-chan string, <-chan error){
    stime:=time.Now()
    tt := make(chan string)
    err:= make(chan error)
    go func() {
        defer func(){
            close(tt)
            close(err)
        }()
        for {
            tt<-time.Now().Format("2006-01-02 15:04:05")
            if time.Now().Sub(stime).Minutes() > 1 {
                return
            }
        }
    }()
    return tt,err
}

客户端:

str,er:=ro.TestCallBack()
    for{
        select{
        case  tt,ok := <- str:
            if !ok { //已经关闭
                fmt.Println("channel closed!")
                return
            }
            fmt.Println(tt)
        case  e,ok:=<-er:
            if ok && e!=nil{
                fmt.Println(e)
                return
            }
        }

    }

运行结果出现错误:

This type is not supported: <-chan string
Process finished with exit code 0

websocket方式时,实现的是每个请求一个链接吗?

我看代码里面每个请求处理完成后就把链接关闭了!

func (service *WebSocketService) ServeHTTP(response http.ResponseWriter, request *http.Request) {
    if request.Method == "GET" && strings.ToLower(request.Header.Get("connection")) != "upgrade" || request.Method == "POST" {
        service.HttpService.ServeHTTP(response, request)
        return
    }
    conn, err := service.Upgrade(response, request, nil)
    if err != nil {
        context := new(HttpContext)
        context.BaseContext = NewBaseContext()
        context.Response = response
        context.Request = request
        service.fireErrorEvent(err, context)
        return
    }
    defer conn.Close()
    mutex := sync.Mutex{}
    for {
        context := new(WebSocketContext)
        context.HttpContext = new(HttpContext)
        context.BaseContext = NewBaseContext()
        context.Response = response
        context.Request = request
        context.WebSocket = conn
        msgType, data, err := conn.ReadMessage()
        if err != nil {
            break
        }
        if msgType == websocket.BinaryMessage {
            go func(conn *websocket.Conn, data []byte, context *WebSocketContext) {
                id := data[0:4]
                data = service.Handle(data[4:], context)
                msg := make([]byte, len(data)+4)
                copy(msg, id)
                copy(msg[4:], data)
                err := func() error {
                    mutex.Lock()
                    defer mutex.Unlock()
                    return conn.WriteMessage(websocket.BinaryMessage, msg)
                }()
                if err != nil {
                    service.fireErrorEvent(err, context)
                    conn.Close()
                }
            }(conn, data, context)
        }
    }
}

请问如何使用返回机构体,然后远程调用结构体方法

服务端代码
`
package main

import (
"net/http"

rpc "github.com/hprose/hprose-golang/rpc/websocket"

)

type Hello struct {
Name string
}

func NewHello(name string) Hello {
return Hello{Name: name}
}

func (this Hello) Hello(speak string) string {
return "Hello " + this.Name + speak + "!"
}

func main() {
service := rpc.NewWebSocketService()
service.AddFunction("newhello", NewHello)
http.ListenAndServe(":8080", service)
}
`
请问客户端如何使用初始化结构后Hello方法,

Server端接口回调

你好,最近看到你们的项目,我这边有一个需求是这样的,不知道能否满足?
�假如我有一台client调用server端一个接口,server端处理完成step 1后,需要回调client端的一个接口,如果client端返回ok,则server端继续执行step 2,否则退出执行?
或者是这样:
假如我有一个clientManger,创建了3个client分发到3台server,每台server处理完step 1之后(各个server处理完成的时间不一致),需要回调client端的接口,询问clientManger其它server是否也处理完了step 1,如果所有的sever都处理完成step 1,则server继续执行step 2,否则等待其它server执行?

hprose golang2.0,http监听默认是tcp6

service := rpc.NewHTTPService()
service.Event = myServiceEvent{}
service.AddFunction("hello", hello)  
http.ListenAndServe(":5881", service)

默认监听是tcp6,怎么弄成tcp4

writer.go 中 fastSerialize 对 *string等 的处理.

一个结构体里存在一个空的 *string, 尝试对这个结构体序列化的时候会产生
panic: runtime error: invalid memory address or nil pointer dereference

诸如 *int, *int64, *map[string]interface{} 之类, 在为 nil 的时候也都如此.

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.