创建服务器
创建 http 服务器
- package main
- import (
- "net/http"
- "github.com/hprose/hprose-golang/rpc"
- )
- func hello(name string) string {
- return "Hello " + name + "!"
- }
- func main() {
- service := rpc.NewHTTPService()
- service.AddFunction("hello", hello)
- http.ListenAndServe(":8080", service)
- }
创建 fasthttp 服务器
- package main
- import (
- rpc "github.com/hprose/hprose-golang/rpc/fasthttp"
- "github.com/valyala/fasthttp"
- )
- func hello(name string) string {
- return "Hello " + name + "!"
- }
- func main() {
- service := rpc.NewFastHTTPService()
- service.AddFunction("hello", hello)
- fasthttp.ListenAndServe(":8080", service.ServeFastHTTP)
- }
对比上面两个服务,我们发现服务函数(方法)的编写和发布上是没有区别的,区别只在于创建服务器所使用的构造函数和启动服务器所使用的库。
上面的例子发布的是单个的函数,实际上不仅仅可以发布单个的函数,还可以同时发布多个函数,多个方法,多个结构体对象等等,后面我们会详细介绍这些。这里以发布 hello
函数为例,目的是为了突出创建服务器这个重点。
注意 import
的路径是有所不同的。
创建 TCP 服务器
- package main
- import (
- "github.com/hprose/hprose-golang/rpc"
- )
- func hello(name string) string {
- return "Hello " + name + "!"
- }
- func main() {
- server := rpc.NewTCPServer("tcp4://0.0.0.0:4321/")
- server.AddFunction("hello", hello)
- server.Start()
- }
同样服务编写和发布没有区别,区别只在于构造函数和服务的启动。在这里我们创建 TCP 服务器时,使用的是 TCPServer
而不是 TCPService
,这可以省去自己创建监听 TCP 服务器的麻烦,但是如果你愿意自己来做这部分也可以,使用 TCPService
就可以了。例如:
- service := rpc.NewTCPService()
- service.AddFunction("hello", hello)
- addr, _ := net.ResolveTCPAddr("tcp", ":4321")
- listener, _ := net.ListenTCP("tcp", addr)
- service.ServeTCP(listener)
当然上面这个使用 service
发布服务的代码只是一个最简单的例子,它并不完备,如果你要自己实现一个完备的 TCP 服务器,还需要做好多工作,上面的代码只是为了说明 service
跟 listener
如何结合。
创建 Unix Socket 服务器
- package main
- import (
- "github.com/hprose/hprose-golang/rpc"
- )
- func hello(name string) string {
- return "Hello " + name + "!"
- }
- func main() {
- server := rpc.NewUnixServer("unix:/tmp/my.sock")
- server.AddFunction("hello", hello)
- server.Start()
- }
这个跟 TCP 服务很类似,不多作介绍了。关于 UnixService
的用法同上面的 TCPService
也是类似的,也略过不做介绍了。
创建 WebSocket 服务器
- package main
- import (
- "net/http"
- rpc "github.com/hprose/hprose-golang/rpc/websocket"
- )
- func hello(name string) string {
- return "Hello " + name + "!"
- }
- func main() {
- service := rpc.NewWebSocketService()
- service.AddFunction("hello", hello)
- http.ListenAndServe(":8080", service)
- }
这个跟 HTTP 服务器的创建很类似,而且这个 WebSocket 的 hprose 服务器,同时也是一个 HTTP 的 hprose 服务器,它可以同时接受 HTTP 和 WebSocket 的 hprose 客户端请求。
注意 import
的路径是有所不同的。
跟 gin 框架结合
HTTP\HTTPS 和 WebSocket 服务并没有单独实现 Server,而只是实现了 Service,所以,这些服务器的启动与关闭依赖于你所使用的 http 库或框架。上面在创建服务器一节中,我们已经介绍了使用 net/http 和 fasthttp 如何来创建服务器。下面我们再举一个在 gin 框架下面如何发布服务的例子:
- package main
- import (
- "github.com/hprose/hprose-golang/rpc"
- "gopkg.in/gin-gonic/gin.v1"
- )
- func hello(name string) string {
- return "Hello " + name + "!"
- }
- func main() {
- service := rpc.NewHTTPService()
- service.AddFunction("hello", hello)
- router := gin.Default()
- router.Any("/path", func(c *gin.Context) {
- service.ServeHTTP(c.Writer, c.Request)
- })
- router.Run(":8080")
- }
上面代码中的 "/path"
可以是任意你希望发布 hprose 服务的路径,一个入口,所有的 Hprose 服务都从这里开始。
WebSocket 服务器跟上面的写法类似,只要把 rpc.NewHTTPService()
换成 rpc.NewWebSocketService()
就可以了,另外注意修改一下导入包的路径。
跟 echo 框架结合
- package main
- import (
- "github.com/hprose/hprose-golang/rpc"
- "github.com/labstack/echo"
- )
- func hello(name string) string {
- return "Hello " + name + "!"
- }
- func main() {
- service := rpc.NewHTTPService()
- service.AddFunction("hello", hello)
- e := echo.New()
- e.Any("/path", echo.WrapHandler(service))
- e.Start(":8080")
- }
上面代码中的 "/path"
可以是任意你希望发布 hprose 服务的路径,一个入口,所有的 Hprose 服务都从这里开始。
WebSocket 服务器跟上面的写法类似,只要把 rpc.NewHTTPService()
换成 rpc.NewWebSocketService()
就可以了。另外注意修改一下导入包的路径。
跟 beego 框架结合
- package main
- import (
- "github.com/astaxie/beego"
- "github.com/hprose/hprose-golang/rpc"
- )
- func hello(name string) string {
- return "Hello " + name + "!"
- }
- func main() {
- service := rpc.NewHTTPService()
- service.AddFunction("hello", hello)
- beego.Handler("/path", service)
- beego.Run()
- }
发布 WebSocket 服务的方式,跟 gin 和 echo 一样。
跟 iris 框架结合
- package main
- import (
- rpc "github.com/hprose/hprose-golang/rpc/fasthttp"
- "github.com/kataras/iris"
- )
- func hello(name string) string {
- return "Hello " + name + "!"
- }
- func main() {
- service := rpc.NewFastHTTPService()
- service.AddFunction("hello", hello)
- iris.Any("/path", func(c *iris.Context) {
- service.ServeFastHTTP(c.RequestCtx)
- })
- iris.Listen(":8080")
- }
跟 gin 和 echo 不同,iris 是基于 fasthttp 的,所以这里创建的是 FastHTTPService
。注意导入包的路径。
Socket 服务器的启动与关闭
下面来介绍一下关于 TCPServer
和 UnixServer
的启动与关闭。
Start 和 Handle 方法区别
TCPServer
和 UnixServer
都包含 Start
和 Handle
两个方法,它俩的功能很接近,都是用于启动服务。区别是:
Handle
启动服务是非阻塞的,Handle
启动服务后,代码会继续执行。
而 Start
启动服务之后会阻塞不再向下执行。Start
启动之后,会监听以下的系统信号:
- syscall.SIGHUP
- syscall.SIGQUIT
- syscall.SIGTERM
- syscall.SIGINT
- syscall.SIGKILL
当收到syscall.SIGHUP
信号时,服务会重启。当收到其它几个信号时,服务会关闭。
Stop 和 Close 方法的区别
Stop
对应 Start
方法,Close
对应 Handle
方法。即,Stop
方法实际上是发送一个 syscall.SIGQUIT
信号给 Start
启动的服务器以结束服务,对于直接使用 Handle
方法启动的服务,Stop
方法无效。使用 Close
方法可以关闭使用 Handle
方法启动的服务。
Restart 方法
Restart
这个也是用于重启使用 Start
方法启动的服务的,对于直接使用 Handle
方法启动的服务无效。