Skip to content
This repository has been archived by the owner on Apr 8, 2024. It is now read-only.

serve web content and grpc? #82

Open
ctaggart opened this issue Jun 17, 2017 · 7 comments
Open

serve web content and grpc? #82

ctaggart opened this issue Jun 17, 2017 · 7 comments

Comments

@ctaggart
Copy link

ctaggart commented Jun 17, 2017

It is cool that this library now builds on httpbin. Is it possible to serve both web content and gRPC content on the same port? This is possible only using Go currently. grpc/grpc#8043

I want to make a single page application that uses gRPC for communication. The single page app just needs to serve an index.html page and some css and image files.

@stepancheg
Copy link
Owner

It should be possible with little development.

But please note that httpbis doesn't support HTTP/1 currently.

@ctaggart
Copy link
Author

It should be possible with little development.

😄

But please note that httpbis doesn't support HTTP/1 currently.

👍 I don't think I need HTTP/1 if those things can be served to Chrome over HTTP/2. It is an internal website where I can have everyone use Chrome.

@stepancheg
Copy link
Owner

grpc::ServerBuilder now (in master) exposes http::ServerBuilder which can be used to attach custom HTTP service implementation.

@ctaggart
Copy link
Author

ctaggart commented Aug 5, 2017

Hi @stepancheg, thank you for making this change! I tried today to make it work, but am stuck. Here is video and the code that I've been trying.

https://youtu.be/6ZAo-xEQNps

modified greeter_server.rs

extern crate futures;

extern crate grpc_examples;
extern crate grpc;
extern crate httpbis;
//extern crate tls_api_stub;
extern crate tls_api_openssl;
extern crate tls_api;

use tls_api::TlsAcceptorBuilder as tls_api_TlsAcceptorBuilder;

use std::thread;

use grpc_examples::helloworld_grpc::*;
use grpc_examples::helloworld::*;
use std::sync::Arc;

struct GreeterImpl;

impl Greeter for GreeterImpl {
    fn say_hello(&self, _m: grpc::RequestOptions, req: HelloRequest) -> grpc::SingleResponse<HelloReply> {
        let mut r = HelloReply::new();
        let name = if req.get_name().is_empty() { "world" } else { req.get_name() };
        println!("greeting request from {}", name);
        r.set_message(format!("Hello {}", name));
        grpc::SingleResponse::completed(r)
    }
}


struct ServiceB;

impl httpbis::Service for ServiceB {
    fn start_request(&self, req_headers: httpbis::Headers, _req: httpbis::HttpPartStream)
                     -> httpbis::Response
    {
        let mut resp_headers = httpbis::Headers::ok_200();
        resp_headers.add("content-type", "text/plain; charset=utf-8");
        httpbis::Response::headers_and_bytes(resp_headers, "service B")
    }
}

fn create_http() -> httpbis::ServerBuilder<tls_api_openssl::TlsAcceptor> {
    let pkcs12 = include_bytes!("../../../../rust-http2/tests/identity.p12");
    let mut tls_acceptor = tls_api_openssl::TlsAcceptorBuilder::from_pkcs12(pkcs12, "mypass")
        .expect("acceptor builder");
    tls_acceptor.set_alpn_protocols(&[b"h2"]).expect("set_alpn_protocols");

    let mut conf = httpbis::ServerConf::new();
    conf.alpn = Some(httpbis::ServerAlpn::Require);
    let mut server = httpbis::ServerBuilder::new();

    server.set_tls(tls_acceptor.build().expect("tls acceptor"));
    server.conf = conf;
    server.service.set_service("/b", Arc::new(ServiceB{}));
    server
}

fn main() {
    let http = create_http();
    let conf = grpc::ServerConf::new();
    let mut server: grpc::ServerBuilder<tls_api_openssl::TlsAcceptor> = grpc::ServerBuilder {http: http, conf: conf };

    server.http.set_port(50051);
    server.add_service(GreeterServer::new_service_def(GreeterImpl));
    server.http.set_cpu_pool_threads(4);
    let _server = server.build().expect("server");

    loop {
        thread::park();
    }
}

@ctaggart
Copy link
Author

ctaggart commented Aug 9, 2017

@stepancheg, can we reopen this until there is a working solution? I was recently laid off and I've got some ideas that I want to explore while I have some free time, but I am blocked until this works.

@stepancheg stepancheg reopened this Aug 9, 2017
@thedodd
Copy link
Contributor

thedodd commented Oct 2, 2017

Serving static content and handling gRPC requests are two very different things. It would be best to simply create a server which uses this lib for gRPC and then rocket, hyper or any other framework to serve static content.

They could exists in the same server. Running in the same container (if that is how you deploy). Same binary. Problem solved.

@ctaggart
Copy link
Author

ctaggart commented Oct 2, 2017

I want to build a website using gRPC like https://github.com/improbable-eng/grpc-web, but with a Rust backend. I'm pretty sure it works with gRPC and other content on the same port. I don't think it is unreasonable. I'll investigate and find out.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants