1
0
mirror of https://github.com/taigrr/wasm-experiments synced 2025-01-18 04:03:21 -08:00

Fix gRPC-Web test!

This commit is contained in:
Johan Brandhorst 2018-05-28 22:29:22 +01:00
parent d8c7440fdb
commit 8e0ab9aedb
No known key found for this signature in database
GPG Key ID: 266C7D9B44EAA057
9 changed files with 471 additions and 180 deletions

View File

@ -1,7 +1,7 @@
generate: generate:
protoc -I. ./proto/web.proto \ protoc -I. ./proto/web.proto \
--go_out=plugins=grpc:$$GOPATH/src --go_out=plugins=grpc:$$GOPATH/src
go generate ./frontend/ go generate -x ./frontend/
serve: serve:
go run main.go go run main.go

View File

@ -3,6 +3,9 @@ package backend
import ( import (
"context" "context"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"github.com/johanbrandhorst/wasm-experiments/grpc/proto/server" "github.com/johanbrandhorst/wasm-experiments/grpc/proto/server"
) )
@ -15,7 +18,10 @@ type Backend struct {
var _ server.BackendServer = (*Backend)(nil) var _ server.BackendServer = (*Backend)(nil)
func (b Backend) GetUser(ctx context.Context, req *server.GetUserRequest) (*server.User, error) { func (b Backend) GetUser(ctx context.Context, req *server.GetUserRequest) (*server.User, error) {
if req.GetUserId() != "1234" {
return nil, status.Error(codes.InvalidArgument, "invalid id")
}
return &server.User{ return &server.User{
Id: "1234", Id: req.GetUserId(),
}, nil }, nil
} }

File diff suppressed because one or more lines are too long

View File

@ -1,12 +1,16 @@
package main package main
import ( import (
"bytes"
"encoding/binary"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"net/http" "net/http"
"net/url"
"github.com/golang/protobuf/proto"
"github.com/johanbrandhorst/fetch" "github.com/johanbrandhorst/fetch"
"github.com/johanbrandhorst/wasm-experiments/grpc/proto/server"
) )
// Build with Go WASM fork // Build with Go WASM fork
@ -20,15 +24,25 @@ func main() {
c := http.Client{ c := http.Client{
Transport: &fetch.Transport{}, Transport: &fetch.Transport{},
} }
req := &http.Request{ b, err := proto.Marshal(&server.GetUserRequest{
Method: "POST", UserId: "1234",
URL: &url.URL{ })
Path: "/web.Backend/GetUser", if err != nil {
}, fmt.Println(err)
Header: http.Header{ return
"Content-Type": []string{"application/grpc-web+proto"},
},
} }
bufHeader := make([]byte, 5)
// Write length of b into buf
binary.BigEndian.PutUint32(bufHeader[1:], uint32(len(b)))
req, err := http.NewRequest("POST", "/web.Backend/GetUser", bytes.NewBuffer(append(bufHeader, b...)))
if err != nil {
fmt.Println(err)
return
}
req.Header.Add("content-type", "application/grpc-web+proto")
//ctx, _ := context.WithTimeout(context.Background(), time.Second) //ctx, _ := context.WithTimeout(context.Background(), time.Second)
//req = req.WithContext(ctx) //req = req.WithContext(ctx)
@ -38,10 +52,53 @@ func main() {
return return
} }
defer resp.Body.Close() defer resp.Body.Close()
b, err := ioutil.ReadAll(resp.Body)
if err != nil { for {
fmt.Println(err) header := make([]byte, 5)
return _, err := resp.Body.Read(header)
if err != nil {
fmt.Println(err)
return
}
if header[0] == 0x80 {
trailers, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(string(trailers))
return
}
length := binary.BigEndian.Uint32(header[1:])
message := make([]byte, length)
_, err = resp.Body.Read(message)
if err != nil {
fmt.Println(err)
return
}
/*
status := resp.Header.Get("grpc-status")
statusCode, err := strconv.Atoi(status)
if err != nil {
fmt.Println(err)
return
}
code := codes.Code(statusCode)
if code != codes.OK {
msg := resp.Header.Get("grpc-message")
fmt.Println(msg)
return
}
*/
user := new(server.User)
err = proto.Unmarshal(message, user)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(user.Id)
} }
fmt.Println(string(b))
} }

View File

@ -7,24 +7,36 @@ license that can be found in the LICENSE file.
<html> <html>
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<title>Go wasm</title> <title>Go wasm</title>
</head> </head>
<body> <body>
<script src="wasm_exec.js"></script> <script src="wasm_exec.js"></script>
<script> <script>
async function loadAndCompile() { if (!WebAssembly.instantiateStreaming) { // polyfill
let resp = await fetch("test.wasm"); WebAssembly.instantiateStreaming = async (resp, importObject) => {
let bytes = await resp.arrayBuffer(); const source = await (await resp).arrayBuffer();
await go.compile(bytes); return await WebAssembly.instantiate(source, importObject);
document.getElementById("runButton").disabled = false; };
} }
loadAndCompile(); const go = new Go();
</script> let mod, inst;
WebAssembly.instantiateStreaming(fetch("test.wasm"), go.importObject).then((result) => {
mod = result.module;
inst = result.instance;
document.getElementById("runButton").disabled = false;
});
<button onClick="console.clear(); go.run();" id="runButton" disabled>Get User</button> async function run() {
console.clear();
await go.run(inst);
inst = await WebAssembly.instantiate(mod, go.importObject); // reset instance
}
</script>
<button onClick="run();" id="runButton" disabled>Run</button>
</body> </body>
</html> </html>

Binary file not shown.

282
grpc/frontend/html/wasm_exec.js Normal file → Executable file
View File

@ -2,20 +2,11 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
(function () { (() => {
let args = ["js"];
// Map web browser API and Node.js API to a single common API (preferring web standards over Node.js API). // Map web browser API and Node.js API to a single common API (preferring web standards over Node.js API).
const isNodeJS = typeof process !== "undefined"; const isNodeJS = typeof process !== "undefined";
if (isNodeJS) { if (isNodeJS) {
if (process.argv.length < 3) {
process.stderr.write("usage: go_js_wasm_exec [wasm binary]\n");
process.exit(1);
}
args = args.concat(process.argv.slice(3));
global.require = require; global.require = require;
global.fs = require("fs"); global.fs = require("fs");
const nodeCrypto = require("crypto"); const nodeCrypto = require("crypto");
@ -40,15 +31,6 @@
} else { } else {
window.global = window; window.global = window;
global.process = {
env: {},
exit(code) {
if (code !== 0) {
console.warn("exit code:", code);
}
},
};
let outputBuf = ""; let outputBuf = "";
global.fs = { global.fs = {
constants: {}, constants: {},
@ -67,154 +49,153 @@
const encoder = new TextEncoder("utf-8"); const encoder = new TextEncoder("utf-8");
const decoder = new TextDecoder("utf-8"); const decoder = new TextDecoder("utf-8");
let mod, inst; global.Go = class {
let values = []; // TODO: garbage collection constructor() {
let resolveResume = function () { }; this.argv = [];
this.env = {};
this.exit = (code) => {
if (code !== 0) {
console.warn("exit code:", code);
}
};
function mem() { const mem = () => {
// The buffer may change when requesting more memory. // The buffer may change when requesting more memory.
return new DataView(inst.exports.mem.buffer); return new DataView(this._inst.exports.mem.buffer);
} }
function setInt64(addr, v) { const setInt64 = (addr, v) => {
mem().setUint32(addr + 0, v, true); mem().setUint32(addr + 0, v, true);
if (v >= 0) { mem().setUint32(addr + 4, Math.floor(v / 4294967296), true);
mem().setUint32(addr + 4, v / 4294967296, true); }
} else {
mem().setUint32(addr + 4, -1, true); // FIXME
}
}
function getInt64(addr) { const getInt64 = (addr) => {
const low = mem().getUint32(addr + 0, true); const low = mem().getUint32(addr + 0, true);
const high = mem().getInt32(addr + 4, true); const high = mem().getInt32(addr + 4, true);
return low + high * 4294967296; return low + high * 4294967296;
} }
function loadValue(addr) { const loadValue = (addr) => {
const id = mem().getUint32(addr, true); const id = mem().getUint32(addr, true);
return values[id]; return this._values[id];
} }
function storeValue(addr, v) { const storeValue = (addr, v) => {
if (v === undefined) { if (v === undefined) {
mem().setUint32(addr, 0, true); mem().setUint32(addr, 0, true);
return; return;
} }
if (v === null) { if (v === null) {
mem().setUint32(addr, 1, true); mem().setUint32(addr, 1, true);
return; return;
} }
values.push(v); this._values.push(v);
mem().setUint32(addr, values.length - 1, true); mem().setUint32(addr, this._values.length - 1, true);
} }
function loadSlice(addr) { const loadSlice = (addr) => {
const array = getInt64(addr + 0); const array = getInt64(addr + 0);
const len = getInt64(addr + 8); const len = getInt64(addr + 8);
return new Uint8Array(inst.exports.mem.buffer, array, len); return new Uint8Array(this._inst.exports.mem.buffer, array, len);
} }
function loadSliceOfValues(addr) { const loadSliceOfValues = (addr) => {
const array = getInt64(addr + 0); const array = getInt64(addr + 0);
const len = getInt64(addr + 8); const len = getInt64(addr + 8);
const a = new Array(len); const a = new Array(len);
for (let i = 0; i < len; i++) { for (let i = 0; i < len; i++) {
const id = mem().getUint32(array + i * 4, true); const id = mem().getUint32(array + i * 4, true);
a[i] = values[id]; a[i] = this._values[id];
} }
return a; return a;
} }
function loadString(addr) { const loadString = (addr) => {
const saddr = getInt64(addr + 0); const saddr = getInt64(addr + 0);
const len = getInt64(addr + 8); const len = getInt64(addr + 8);
return decoder.decode(new DataView(inst.exports.mem.buffer, saddr, len)); return decoder.decode(new DataView(this._inst.exports.mem.buffer, saddr, len));
} }
global.go = { this.importObject = {
exited: false,
compileAndRun: async function (source) {
await go.compile(source);
await go.run();
},
compile: async function (source) {
mod = await WebAssembly.compile(source);
},
run: async function () {
let importObject = {
go: { go: {
// func wasmExit(code int32) // func wasmExit(code int32)
"runtime.wasmExit": function (sp) { "runtime.wasmExit": (sp) => {
go.exited = true; this.exited = true;
process.exit(mem().getInt32(sp + 8, true)); this.exit(mem().getInt32(sp + 8, true));
}, },
// func wasmWrite(fd uintptr, p unsafe.Pointer, n int32) // func wasmWrite(fd uintptr, p unsafe.Pointer, n int32)
"runtime.wasmWrite": function (sp) { "runtime.wasmWrite": (sp) => {
const fd = getInt64(sp + 8); const fd = getInt64(sp + 8);
const p = getInt64(sp + 16); const p = getInt64(sp + 16);
const n = mem().getInt32(sp + 24, true); const n = mem().getInt32(sp + 24, true);
fs.writeSync(fd, new Uint8Array(inst.exports.mem.buffer, p, n)); fs.writeSync(fd, new Uint8Array(this._inst.exports.mem.buffer, p, n));
}, },
// func nanotime() int64 // func nanotime() int64
"runtime.nanotime": function (sp) { "runtime.nanotime": (sp) => {
setInt64(sp + 8, (performance.timeOrigin + performance.now()) * 1000000); setInt64(sp + 8, (performance.timeOrigin + performance.now()) * 1000000);
}, },
// func walltime() (sec int64, nsec int32) // func walltime() (sec int64, nsec int32)
"runtime.walltime": function (sp) { "runtime.walltime": (sp) => {
const msec = (new Date).getTime(); const msec = (new Date).getTime();
setInt64(sp + 8, msec / 1000); setInt64(sp + 8, msec / 1000);
mem().setInt32(sp + 16, (msec % 1000) * 1000000, true); mem().setInt32(sp + 16, (msec % 1000) * 1000000, true);
}, },
// func scheduleCallback(delay int64)
"runtime.scheduleCallback": (sp) => {
setTimeout(() => { this._resolveCallbackPromise(); }, getInt64(sp + 8));
},
// func getRandomData(r []byte)
"runtime.getRandomData": (sp) => {
crypto.getRandomValues(loadSlice(sp + 8));
},
// func boolVal(value bool) Value // func boolVal(value bool) Value
"syscall/js.boolVal": function (sp) { "syscall/js.boolVal": (sp) => {
storeValue(sp + 16, mem().getUint8(sp + 8) !== 0); storeValue(sp + 16, mem().getUint8(sp + 8) !== 0);
}, },
// func intVal(value int) Value // func intVal(value int) Value
"syscall/js.intVal": function (sp) { "syscall/js.intVal": (sp) => {
storeValue(sp + 16, getInt64(sp + 8)); storeValue(sp + 16, getInt64(sp + 8));
}, },
// func floatVal(value float64) Value // func floatVal(value float64) Value
"syscall/js.floatVal": function (sp) { "syscall/js.floatVal": (sp) => {
storeValue(sp + 16, mem().getFloat64(sp + 8, true)); storeValue(sp + 16, mem().getFloat64(sp + 8, true));
}, },
// func stringVal(value string) Value // func stringVal(value string) Value
"syscall/js.stringVal": function (sp) { "syscall/js.stringVal": (sp) => {
storeValue(sp + 24, loadString(sp + 8)); storeValue(sp + 24, loadString(sp + 8));
}, },
// func (v Value) Get(key string) Value // func (v Value) Get(key string) Value
"syscall/js.Value.Get": function (sp) { "syscall/js.Value.Get": (sp) => {
storeValue(sp + 32, Reflect.get(loadValue(sp + 8), loadString(sp + 16))); storeValue(sp + 32, Reflect.get(loadValue(sp + 8), loadString(sp + 16)));
}, },
// func (v Value) set(key string, value Value) // func (v Value) set(key string, value Value)
"syscall/js.Value.set": function (sp) { "syscall/js.Value.set": (sp) => {
Reflect.set(loadValue(sp + 8), loadString(sp + 16), loadValue(sp + 32)); Reflect.set(loadValue(sp + 8), loadString(sp + 16), loadValue(sp + 32));
}, },
// func (v Value) Index(i int) Value // func (v Value) Index(i int) Value
"syscall/js.Value.Index": function (sp) { "syscall/js.Value.Index": (sp) => {
storeValue(sp + 24, Reflect.get(loadValue(sp + 8), getInt64(sp + 16))); storeValue(sp + 24, Reflect.get(loadValue(sp + 8), getInt64(sp + 16)));
}, },
// func (v Value) setIndex(i int, value Value) // func (v Value) setIndex(i int, value Value)
"syscall/js.Value.setIndex": function (sp) { "syscall/js.Value.setIndex": (sp) => {
Reflect.set(loadValue(sp + 8), getInt64(sp + 16), loadValue(sp + 24)); Reflect.set(loadValue(sp + 8), getInt64(sp + 16), loadValue(sp + 24));
}, },
// func (v Value) call(name string, args []Value) (Value, bool) // func (v Value) call(name string, args []Value) (Value, bool)
"syscall/js.Value.call": function (sp) { "syscall/js.Value.call": (sp) => {
try { try {
const v = loadValue(sp + 8); const v = loadValue(sp + 8);
const m = Reflect.get(v, loadString(sp + 16)); const m = Reflect.get(v, loadString(sp + 16));
@ -228,7 +209,7 @@
}, },
// func (v Value) invoke(args []Value) (Value, bool) // func (v Value) invoke(args []Value) (Value, bool)
"syscall/js.Value.invoke": function (sp) { "syscall/js.Value.invoke": (sp) => {
try { try {
const v = loadValue(sp + 8); const v = loadValue(sp + 8);
const args = loadSliceOfValues(sp + 16); const args = loadSliceOfValues(sp + 16);
@ -241,7 +222,7 @@
}, },
// func (v Value) new(args []Value) (Value, bool) // func (v Value) new(args []Value) (Value, bool)
"syscall/js.Value.new": function (sp) { "syscall/js.Value.new": (sp) => {
try { try {
const v = loadValue(sp + 8); const v = loadValue(sp + 8);
const args = loadSliceOfValues(sp + 16); const args = loadSliceOfValues(sp + 16);
@ -254,102 +235,125 @@
}, },
// func (v Value) Float() float64 // func (v Value) Float() float64
"syscall/js.Value.Float": function (sp) { "syscall/js.Value.Float": (sp) => {
mem().setFloat64(sp + 16, parseFloat(loadValue(sp + 8)), true); mem().setFloat64(sp + 16, parseFloat(loadValue(sp + 8)), true);
}, },
// func (v Value) Int() int // func (v Value) Int() int
"syscall/js.Value.Int": function (sp) { "syscall/js.Value.Int": (sp) => {
setInt64(sp + 16, parseInt(loadValue(sp + 8))); setInt64(sp + 16, parseInt(loadValue(sp + 8)));
}, },
// func (v Value) Bool() bool // func (v Value) Bool() bool
"syscall/js.Value.Bool": function (sp) { "syscall/js.Value.Bool": (sp) => {
mem().setUint8(sp + 16, !!loadValue(sp + 8)); mem().setUint8(sp + 16, !!loadValue(sp + 8));
}, },
// func (v Value) Length() int // func (v Value) Length() int
"syscall/js.Value.Length": function (sp) { "syscall/js.Value.Length": (sp) => {
setInt64(sp + 16, parseInt(loadValue(sp + 8).length)); setInt64(sp + 16, parseInt(loadValue(sp + 8).length));
}, },
// func (v Value) prepareString() (Value, int) // func (v Value) prepareString() (Value, int)
"syscall/js.Value.prepareString": function (sp) { "syscall/js.Value.prepareString": (sp) => {
const str = encoder.encode(String(loadValue(sp + 8))); const str = encoder.encode(String(loadValue(sp + 8)));
storeValue(sp + 16, str); storeValue(sp + 16, str);
setInt64(sp + 24, str.length); setInt64(sp + 24, str.length);
}, },
// func (v Value) loadString(b []byte) // func (v Value) loadString(b []byte)
"syscall/js.Value.loadString": function (sp) { "syscall/js.Value.loadString": (sp) => {
const str = loadValue(sp + 8); const str = loadValue(sp + 8);
loadSlice(sp + 16).set(str); loadSlice(sp + 16).set(str);
}, },
"debug": function (value) { "debug": (value) => {
console.log(value); console.log(value);
}, },
} }
}; };
}
inst = await WebAssembly.instantiate(mod, importObject); async run(instance) {
values = [ this._inst = instance;
this._values = [ // TODO: garbage collection
undefined, undefined,
null, null,
global, global,
inst.exports.mem, this._inst.exports.mem,
function () { resolveResume(); }, () => {
if (this.exited) {
throw new Error("bad callback: Go program has already exited");
}
setTimeout(this._resolveCallbackPromise, 0); // make sure it is asynchronous
},
]; ];
this.exited = false;
const mem = new DataView(this._inst.exports.mem.buffer)
// Pass command line arguments and environment variables to WebAssembly by writing them to the linear memory. // Pass command line arguments and environment variables to WebAssembly by writing them to the linear memory.
let offset = 4096; let offset = 4096;
const strPtr = (str) => { const strPtr = (str) => {
let ptr = offset; let ptr = offset;
new Uint8Array(inst.exports.mem.buffer, offset, str.length + 1).set(encoder.encode(str + "\0")); new Uint8Array(mem.buffer, offset, str.length + 1).set(encoder.encode(str + "\0"));
offset += str.length + (8 - (str.length % 8)); offset += str.length + (8 - (str.length % 8));
return ptr; return ptr;
}; };
const argc = args.length; const argc = this.argv.length;
const argvPtrs = []; const argvPtrs = [];
args.forEach((arg) => { this.argv.forEach((arg) => {
argvPtrs.push(strPtr(arg)); argvPtrs.push(strPtr(arg));
}); });
const keys = Object.keys(process.env).sort(); const keys = Object.keys(this.env).sort();
argvPtrs.push(keys.length); argvPtrs.push(keys.length);
keys.forEach((key) => { keys.forEach((key) => {
argvPtrs.push(strPtr(`${key}=${process.env[key]}`)); argvPtrs.push(strPtr(`${key}=${this.env[key]}`));
}); });
const argv = offset; const argv = offset;
argvPtrs.forEach((ptr) => { argvPtrs.forEach((ptr) => {
mem().setUint32(offset, ptr, true); mem.setUint32(offset, ptr, true);
mem().setUint32(offset + 4, 0, true); mem.setUint32(offset + 4, 0, true);
offset += 8; offset += 8;
}); });
try { while (true) {
while (true) { const callbackPromise = new Promise((resolve) => {
inst.exports.run(argc, argv); this._resolveCallbackPromise = resolve;
if (go.exited) { });
break; this._inst.exports.run(argc, argv);
} if (this.exited) {
await new Promise((resolve) => { break;
resolveResume = resolve;
});
} }
} catch (err) { await callbackPromise;
console.error(err);
process.exit(1);
} }
}, }
} }
if (isNodeJS) { if (isNodeJS) {
go.compileAndRun(fs.readFileSync(process.argv[2])).catch((err) => { if (process.argv.length < 3) {
process.stderr.write("usage: go_js_wasm_exec [wasm binary] [arguments]\n");
process.exit(1);
}
const go = new Go();
go.argv = process.argv.slice(2);
go.env = process.env;
go.exit = process.exit;
WebAssembly.instantiate(fs.readFileSync(process.argv[2]), go.importObject).then((result) => {
process.on("exit", () => { // Node.js exits if no callback is pending
if (!go.exited) {
console.error("error: all goroutines asleep and no JavaScript callback pending - deadlock!");
process.exit(1);
}
});
return go.run(result.instance);
}).catch((err) => {
console.error(err); console.error(err);
process.exit(1); process.exit(1);
}); });

View File

@ -49,7 +49,7 @@ func main() {
wrappedServer.ServeHTTP(resp, req) wrappedServer.ServeHTTP(resp, req)
} else { } else {
// Serve the GopherJS client // Serve the GopherJS client
folderReader(gzipped.FileServer(bundle.Assets)).ServeHTTP(resp, req) wasmContentTypeSetter(folderReader(gzipped.FileServer(bundle.Assets))).ServeHTTP(resp, req)
} }
} }
@ -73,12 +73,24 @@ func main() {
logger.Fatal(httpsSrv.ListenAndServeTLS("./cert.pem", "./key.pem")) logger.Fatal(httpsSrv.ListenAndServeTLS("./cert.pem", "./key.pem"))
} }
func wasmContentTypeSetter(fn http.Handler) http.HandlerFunc {
return func(w http.ResponseWriter, req *http.Request) {
if strings.Contains(req.URL.Path, ".wasm") {
w.Header().Set("content-type", "application/wasm")
}
fn.ServeHTTP(w, req)
}
}
func folderReader(fn http.Handler) http.HandlerFunc { func folderReader(fn http.Handler) http.HandlerFunc {
return func(w http.ResponseWriter, req *http.Request) { return func(w http.ResponseWriter, req *http.Request) {
if strings.HasSuffix(req.URL.Path, "/") { if strings.HasSuffix(req.URL.Path, "/") {
// Use contents of index.html for directory, if present. // Use contents of index.html for directory, if present.
req.URL.Path = path.Join(req.URL.Path, "index.html") req.URL.Path = path.Join(req.URL.Path, "index.html")
} }
if req.URL.Path == "/test.wasm" {
w.Header().Set("content-type", "application/wasm")
}
fn.ServeHTTP(w, req) fn.ServeHTTP(w, req)
} }
} }

200
grpc/proto/client/web.pb.go Normal file
View File

@ -0,0 +1,200 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: proto/web.proto
package server // import "github.com/johanbrandhorst/wasm-experiments/grpc/proto/client"
/*
Web exposes a backend server over gRPC.
*/
import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import math "math"
import (
context "golang.org/x/net/context"
grpc "google.golang.org/grpc"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
type GetUserRequest struct {
UserId string `protobuf:"bytes,1,opt,name=user_id,json=userId" json:"user_id,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *GetUserRequest) Reset() { *m = GetUserRequest{} }
func (m *GetUserRequest) String() string { return proto.CompactTextString(m) }
func (*GetUserRequest) ProtoMessage() {}
func (*GetUserRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_web_19a831568a3bf959, []int{0}
}
func (m *GetUserRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_GetUserRequest.Unmarshal(m, b)
}
func (m *GetUserRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_GetUserRequest.Marshal(b, m, deterministic)
}
func (dst *GetUserRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_GetUserRequest.Merge(dst, src)
}
func (m *GetUserRequest) XXX_Size() int {
return xxx_messageInfo_GetUserRequest.Size(m)
}
func (m *GetUserRequest) XXX_DiscardUnknown() {
xxx_messageInfo_GetUserRequest.DiscardUnknown(m)
}
var xxx_messageInfo_GetUserRequest proto.InternalMessageInfo
func (m *GetUserRequest) GetUserId() string {
if m != nil {
return m.UserId
}
return ""
}
type User struct {
Id string `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *User) Reset() { *m = User{} }
func (m *User) String() string { return proto.CompactTextString(m) }
func (*User) ProtoMessage() {}
func (*User) Descriptor() ([]byte, []int) {
return fileDescriptor_web_19a831568a3bf959, []int{1}
}
func (m *User) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_User.Unmarshal(m, b)
}
func (m *User) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_User.Marshal(b, m, deterministic)
}
func (dst *User) XXX_Merge(src proto.Message) {
xxx_messageInfo_User.Merge(dst, src)
}
func (m *User) XXX_Size() int {
return xxx_messageInfo_User.Size(m)
}
func (m *User) XXX_DiscardUnknown() {
xxx_messageInfo_User.DiscardUnknown(m)
}
var xxx_messageInfo_User proto.InternalMessageInfo
func (m *User) GetId() string {
if m != nil {
return m.Id
}
return ""
}
func init() {
proto.RegisterType((*GetUserRequest)(nil), "web.GetUserRequest")
proto.RegisterType((*User)(nil), "web.User")
}
// Reference imports to suppress errors if they are not otherwise used.
var _ context.Context
var _ grpc.ClientConn
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
const _ = grpc.SupportPackageIsVersion4
// Client API for Backend service
type BackendClient interface {
GetUser(ctx context.Context, in *GetUserRequest, opts ...grpc.CallOption) (*User, error)
}
type backendClient struct {
cc *grpc.ClientConn
}
func NewBackendClient(cc *grpc.ClientConn) BackendClient {
return &backendClient{cc}
}
func (c *backendClient) GetUser(ctx context.Context, in *GetUserRequest, opts ...grpc.CallOption) (*User, error) {
out := new(User)
err := grpc.Invoke(ctx, "/web.Backend/GetUser", in, out, c.cc, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// Server API for Backend service
type BackendServer interface {
GetUser(context.Context, *GetUserRequest) (*User, error)
}
func RegisterBackendServer(s *grpc.Server, srv BackendServer) {
s.RegisterService(&_Backend_serviceDesc, srv)
}
func _Backend_GetUser_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(GetUserRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(BackendServer).GetUser(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/web.Backend/GetUser",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(BackendServer).GetUser(ctx, req.(*GetUserRequest))
}
return interceptor(ctx, in, info, handler)
}
var _Backend_serviceDesc = grpc.ServiceDesc{
ServiceName: "web.Backend",
HandlerType: (*BackendServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "GetUser",
Handler: _Backend_GetUser_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "proto/web.proto",
}
func init() { proto.RegisterFile("proto/web.proto", fileDescriptor_web_19a831568a3bf959) }
var fileDescriptor_web_19a831568a3bf959 = []byte{
// 197 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x2f, 0x28, 0xca, 0x2f,
0xc9, 0xd7, 0x2f, 0x4f, 0x4d, 0xd2, 0x03, 0xb3, 0x84, 0x98, 0xcb, 0x53, 0x93, 0x94, 0x34, 0xb9,
0xf8, 0xdc, 0x53, 0x4b, 0x42, 0x8b, 0x53, 0x8b, 0x82, 0x52, 0x0b, 0x4b, 0x53, 0x8b, 0x4b, 0x84,
0xc4, 0xb9, 0xd8, 0x4b, 0x8b, 0x53, 0x8b, 0xe2, 0x33, 0x53, 0x24, 0x18, 0x15, 0x18, 0x35, 0x38,
0x83, 0xd8, 0x40, 0x5c, 0xcf, 0x14, 0x25, 0x31, 0x2e, 0x16, 0x90, 0x3a, 0x21, 0x3e, 0x2e, 0x26,
0xb8, 0x1c, 0x53, 0x66, 0x8a, 0x91, 0x19, 0x17, 0xbb, 0x53, 0x62, 0x72, 0x76, 0x6a, 0x5e, 0x8a,
0x90, 0x36, 0x17, 0x3b, 0xd4, 0x34, 0x21, 0x61, 0x3d, 0x90, 0x4d, 0xa8, 0x66, 0x4b, 0x71, 0x82,
0x05, 0x41, 0x22, 0x4a, 0x0c, 0x4e, 0xf6, 0x51, 0xb6, 0xe9, 0x99, 0x25, 0x19, 0xa5, 0x49, 0x7a,
0xc9, 0xf9, 0xb9, 0xfa, 0x59, 0xf9, 0x19, 0x89, 0x79, 0x49, 0x45, 0x89, 0x79, 0x29, 0x19, 0xf9,
0x45, 0xc5, 0x25, 0xfa, 0xe5, 0x89, 0xc5, 0xb9, 0xba, 0xa9, 0x15, 0x05, 0xa9, 0x45, 0x99, 0xb9,
0xa9, 0x79, 0x25, 0xc5, 0xfa, 0xe9, 0x45, 0x05, 0xc9, 0xfa, 0x10, 0x3f, 0x14, 0xa7, 0x16, 0x95,
0xa5, 0x16, 0x25, 0xb1, 0x81, 0x79, 0xc6, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x64, 0xf1,
0x41, 0xda, 0x00, 0x00, 0x00,
}