請求URL:php
https://api.xxx.com/Tbsapi/v1/ip2addr?ip=219.140.227.235
請求方式:git
參數:github
參數名 | 類型 | 說明 |
---|---|---|
ip | url-qurey-string | 可選 要查詢的ip地址,若是不傳這表示當前的ip |
返回示例golang
{ "code": 1, "data": { "Country": "中國", "Province": "湖北省", "City": "武漢", "ISP": "", "Latitude": 30.5801, "Longitude": 114.2734, "TimeZone": "Asia/Shanghai" }, "ip": "219.140.227.235" }
json_rpctcp
地址:121.40.238.123
(IP地址更快)api.turboes.com
端口:3344
Go官方提供了一個RPC庫: net/rpc。包rpc提供了經過網絡訪問一個對象的方法的能力。服務器須要註冊對象, 經過對象的類型名暴露這個服務。註冊後這個對象的輸出方法就能夠遠程調用,這個庫封裝了底層傳輸的細節,包括序列化。服務器能夠註冊多個不一樣類型的對象,可是註冊相同類型的多個對象的時候回出錯。數據庫
- 方法的類型是可輸出的 (the method's type is exported)
- 方法自己也是可輸出的 (the method is exported)
- 方法必須由兩個參數,必須是輸出類型或者是內建類型 (the method has two arguments, both exported or builtin types)
- 方法的第二個參數是指針類型 (the method's second argument is a pointer)
- 方法返回類型爲 error (the method has return type error)
package main import ( "fmt" "github.com/oschwald/geoip2-golang" "net" "net/rpc" "net/rpc/jsonrpc" "os" "log" ) //返回值結構體 //須要知足以上要求 type Response struct { Country string Province string City string ISP string Latitude float64 Longitude float64 TimeZone string } type Ip2addr struct { db *geoip2.Reader } //參數結構體 //須要知足以上要求 type Agrs struct { IpString string } //json rpc 處理請求 //須要知足以上要求 func (t *Ip2addr) Address(agr *Agrs, res *Response) error { netIp := net.ParseIP(agr.IpString) record, err := t.db.City(netIp) res.City = record.City.Names["zh-CN"] res.Province = record.Subdivisions[0].Names["zh-CN"] res.Country = record.Country.Names["zh-CN"] res.Latitude = record.Location.Latitude res.Longitude = record.Location.Longitude res.TimeZone = record.Location.TimeZone return err } func main() { //加載geoIp數據庫 db, err := geoip2.Open("./GeoLite2-City.mmdb") if err != nil { log.Fatal(err) } //初始化jsonRPC ip2addr := &Ip2addr{db} //註冊 rpc.Register(ip2addr) //綁定端口 address := ":3344" tcpAddr, err := net.ResolveTCPAddr("tcp", address) checkError(err) listener, err := net.ListenTCP("tcp", tcpAddr) checkError(err) log.Println("json rpc is listening",tcpAddr) for { conn, err := listener.Accept() if err != nil { continue } jsonrpc.ServeConn(conn) } } func checkError(err error) { if err != nil { fmt.Println("Fatal error ", err.Error()) os.Exit(1) } }
class JsonRPC { public $conn; function __construct($host, $port) { $this->conn = fsockopen($host, $port, $errno, $errstr, 3); if (!$this->conn) { return false; } } public function Call($method, $params) { $obj = new stdClass(); $obj->code = 0; if (!$this->conn) { $obj->info = "jsonRPC鏈接失敗!請聯繫qzhou@turboes.com"; return $obj; } $err = fwrite($this->conn, json_encode(array( 'method' => $method, 'params' => array($params), 'id' => 0, )) . "\n"); if ($err === false) { fclose($this->conn); $obj->info = "jsonRPC發送參數失敗!請檢查本身的rpc-client代碼"; return $obj; } stream_set_timeout($this->conn, 0, 3000); $line = fgets($this->conn); fclose($this->conn); if ($line === false) { $obj->info = "jsonRPC返回消息爲空!請檢查本身的rpc-client代碼"; return $obj; } $temp = json_decode($line); $obj->code = $temp->error == null ? 1 : 0; $obj->data = $temp->result; return $obj; } } function json_rpc_ip_address($ipString) { $client = new JsonRPC("127.0.0.1", 3344); $obj = $client->Call("Ip2addr.Address", ['IpString' => $ipString]); return $obj; }
package main import ( "fmt" "log" "net/rpc/jsonrpc" ) type Response struct { Country string Province string City string ISP string Latitude float64 Longitude float64 TimeZone string } type Agrs struct { IpString string } func main() { client, err := jsonrpc.Dial("tcp", "121.40.238.123:3344") if err != nil { log.Fatal("dialing:", err) } // Synchronous call var res Response err = client.Call("Ip2addr.Address", Agrs{"219.140.227.235"}, &res) if err != nil { log.Fatal("ip2addr error:", err) } fmt.Println(res) }