I'm trying to write a simple WCF Server + gSOAP client proof-of-concept application using SOAP 1.2 protocol. Here's server code:
[ServiceContract(Namespace="http://test.com")]
public interface IService1
{
[OperationContract]
void HelloWorld();
}
[ServiceBehavior(Namespace = "http://test.com")]
public class Service1 : IService1
{
public void HelloWorld()
{
}
}
static void Main(string[] args)
{
var svc = new Service1();
Uri uri = new Uri("http://localhost:8201/Service1");
ServiceHost host = new ServiceHost(typeof(Service1), uri);
host.Description.Namespace = "http://test.com";
var binding = new WSHttpBinding() { Namespace = "http://test.com" };
ServiceEndpoint endpoint = host.AddServiceEndpoint(typeof(IService1), binding, uri);
endpoint.Behaviors.Add(new InlineXsdInWsdlBehavior());
host.Description.Behaviors.Add(new ServiceMetadataBehavior() { HttpGetEnabled = true });
var mex = host.AddServiceEndpoint(typeof(IMetadataExchange), MetadataExchangeBindings.CreateMexHttpBinding(), "mex");
host.Open();
Console.ReadLine();
}
Then I launch service and generate code using following commands:
wsdl2h.exe -gyf -t WS/WS-typemap.dat -o Service.h http://localhost:8201/Service1?wsdl WS/WS-Addressing05.xsd
soapcpp2.exe -C -L -w -x -i -2 Service.h -ID:\...\gsoap-2.7\gsoap\import
Then I compile following C++ code:
#include "soapWSHttpBinding_USCOREIService1Proxy.h"
#include "WSHttpBinding_USCOREIService1.nsmap"
#include "stdsoap2.h"
int _tmain(int argc, _TCHAR* argv[])
{
WSHttpBinding_USCOREIService1Proxy svc;
_ns1__HelloWorld req;
_ns1__HelloWorldResponse rsp;
int hr = svc.HelloWorld( &req, &rsp );
if ( hr != SOAP_OK )
{
_tprintf( _T("Error: %i\n"), hr );
}
return 0;
}
and this generates error 8 (SOAP_MUSTUNDERSTAND). Have anyone ever generated working WCF to gSOAP link at all? What am I doing wrong?
I guess -a switch in soapcpp2 have fixed error 8, so the switches are now:
soapcpp2.exe -C -L -w -x -i -2 -a Service.h -I<...path...>
Related
Here I discuss the implementation of GraphQL in my Project data structure.
In my project, I am using flat files(text files) fixed-width format for DB management. I want to integrate API developments with that. flat files queried from CPP program. In this case, I struggle to choose GraphQL API for CPP Node Addon Native modules (OR) Nodejs NPM module GraphQL.
case 1: Is there a way to use flat file configuration for the NPM GraphQL package?
case 2: Is there a way to write Node Native moduels using node-addon-api? (For CPP developers used GraphQL parser from the opensource project in github named as cppgraphqlgen)
If I am choosing the second case, I am facing the following issues.
I am trying to write as cppgraphqlgen service as node addon native modules. I refer to more topics about that. In my project, some modules were already written in CPP Node addon Native modules using Napi.h. In this cppgraphqlgen project written in different API like nan.h. cppgraphiql uses Nan. I struggle to write these services as node addons for my project.
In my project Make file likes below:
CFLAGS = -Os -O3 -fPIC -Ofast -std=gnu++17
CC = gcc
CXX = g++
LDFLAGS := \
-pthread \
-rdynamic
DEFS := \
'-DUSING_UV_SHARED=1' \
'-DUSING_V8_SHARED=1' \
'-DV8_DEPRECATION_WARNINGS=1' \
'-DV8_DEPRECATION_WARNINGS' \
'-DV8_IMMINENT_DEPRECATION_WARNINGS' \
'-D_LARGEFILE_SOURCE' \
'-D_FILE_OFFSET_BITS=64' \
'-DOPENSSL_NO_PINSHARED' \
'-DOPENSSL_THREADS' \
'-D__STDC_FORMAT_MACROS' \
'-DNAPI_DISABLE_CPP_EXCEPTIONS' \
'-DBUILDING_NODE_EXTENSION'
# Flags passed to all source files.
GYP_CFLAGS := \
-frtti \
-fexceptions \
-pthread \
-Wall \
-Wextra \
-Wno-unused-parameter \
-fno-omit-frame-pointer
# Flags passed to only C files.
CFLAGS_C :=
# Flags passed to only C++ files.
CFLAGS_CC := \
-std=gnu++1y \
-fexceptions
INC_NAPI := -I/usr/include/node-addon-api
INC_NODE := -I/usr/include/node
CGI_LIB = -lcgicc
LIBS := ../cppgraphqlgen/src
NOTH_A = nothing.a
OBJ = nothing.o ./hello/HelloClient.o
ENODE = ${NOTH_A} ./hello/HelloClient.node
# GREET_DEMO = ./greet-demo
# CLASS_DEMO = ./class-demo
DEMO := ./today
HELLO := ./hello
target: ${OBJ} ${ENODE}
clean:
rm -rf *.o *.node *.a
rm -rf ${DEMO}/*.o ${DEMO}/*.node
rm -rf ${HELLO}/*.o ${HELLO}/*.node
# ./hello/hello: ./hello/hello.cpp
# ${CXX} ${CFLAGS} $< -o $#
./hello/hello:
${CXX} ${CFLAGS} ./hello/hello.cpp -shared -Wl,-soname=hello.node -Wl,--start-group -L${LIBS}/separategraphql.a -L${LIBS}/graphqljson.a -L${LIBS}/separateschema.a -L${LIBS}/graphqlintrospection.a -L${LIBS}/graphqlservice.a -L${LIBS}/graphqlresponse.a -L${LIBS}/graphqlpeg.a -lpthread ${NOTH_A} -Wl,--end-group -o $#
./hello/HelloClient.o: ./hello/HelloClient.cpp
${CXX} ${CFLAGS} '-DNODE_GYP_MODULE_NAME=HelloClient' ${DEFS} ${GYP_CFLAGS} ${CFLAGS_CC} ${INC_NAPI} ${INC_NODE} $< -o $#
./hello/HelloClient.node: ./hello/HelloClient.o
${CXX} ${CFLAGS} -shared -Wl,-soname=HelloClient.node -Wl,--start-group ./hello/HelloClient.o -L${LIBS}/separategraphql.a -L${LIBS}/graphqljson.a -L${LIBS}/separateschema.a -L${LIBS}/graphqlintrospection.a -L${LIBS}/graphqlservice.a -L${LIBS}/graphqlresponse.a -L${LIBS}/graphqlpeg.a -lpthread ${NOTH_A} -Wl,--end-group -o $#
nothing.a: nothing.o
ar crs nothing.a $<
nothing.o: nothing.c
${CC} ${LDFLAGS} ${INC_NODE} ${DEFS} -c $< -o $#
In cppgraphqlgen has two services named schemegen and clientgen. the mentioned two services are built successfully. This utility uses CMake (requires GNU 10.3.0). But in my project has the utility GNU Make. My make utility build command doesn't compile sample programs of cppgraphqlgen projects with node-addon-api (Napi.h). I want a simple getting-started program for cppgraphqlgen project.
For Example:
using schemagen service, the Auto-Generated files are HelloSchema.cpp and HelloSchema.h
using clientgen service, the Auto-Generated files are HelloClient.cpp and HelloClient.h
I changed HelloClient.cpp as node addon native
HelloClient.cpp
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
// WARNING! Do not edit this file manually, your changes will be overwritten.
#include <napi.h>
#include "HelloClient.h"
#include <algorithm>
#include <array>
#include <stdexcept>
#include <sstream>
#include <string_view>
using namespace std::literals;
namespace graphql::client {
using namespace query::Query;
namespace query::Query {
const std::string& GetRequestText() noexcept
{
static const auto s_request = R"gql(
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.
query {
hello
}
)gql"s;
return s_request;
}
const peg::ast& GetRequestObject() noexcept
{
static const auto s_request = []() noexcept {
auto ast = peg::parseString(GetRequestText());
// This has already been validated against the schema by clientgen.
ast.validated = true;
return ast;
}();
return s_request;
}
Response parseResponse(response::Value&& response)
{
Response result;
if (response.type() == response::Type::Map)
{
auto members = response.release<response::MapType>();
for (auto& member:members)
{
if (member.first == R"js(hello)js"sv)
{
result.hello = ModifiedResponse<response::StringType>::parse<TypeModifier::Nullable>(std::move(member.second));
continue;
}
}
}
return result;
}
} // namespace query::Query
} // namespace graphql::client
Napi::Object InitAll(Napi::Env env, Napi::Object exports) {
// auto expected = "Test String";
// auto actual = graphql::response::Value(expected);
// std::string res = graphql::client::query::Query::parseResponse(actual);
exports.Set("test", "test"); // <--- Here How to call and get the result "Hello World!"
return exports;
}
NODE_API_MODULE(NODE_GYP_MODULE_NAME, InitAll);
Input schema
type Query {
hello: String
}
Input Query:
{hello}
Output like:
{"data":{"hello":"Hello World!"}}
Another try like samples program in that project folder named today (sample.cpp using TodayMock. I try to write HelloMock)
HelloMock.h
#pragma once
#ifndef HELLOMOCK_H
#define HELLOMOCK_H
#include "HelloSchema.h"
#include <atomic>
#include <stack>
namespace graphql::hello
{
class Query
{
public:
using greetMsg = std::function<std::optional<response::StringType>>();
explicit Query(greetMsg &&getHello);
virtual service::FieldResult<std::optional<response::StringType>> getHello() final;
};
}
#endif // HELLOMOCK_H
HelloMock.cpp
#include "HelloMock.h"
#include <algorithm>
#include <iostream>
namespace graphql::hello
{
Query::Query(greetMsg &&getHello)
{
}
service::FieldResult<std::optional<response::StringType>> Query::getHello()
{
return "Hello World";
}
} // namespace graphql::hello
hello.cpp
#include "HelloMock.h"
#include "graphqlservice/JSONResponse.h"
#include <cstdio>
#include <iostream>
#include <iterator>
#include <stdexcept>
using namespace graphql;
int main(int argc, char **argv)
{
/* From HelloMock*/
response::StringType helloKey;
std::string fakeHelloKey("hello");
helloKey.resize(fakeHelloKey.size());
std::copy(fakeHelloKey.cbegin(), fakeHelloKey.cend(), helloKey.begin());
std::cout << "Created the service..." << std::endl;
auto query = std::make_shared<hello::Query>(
[&fakeHelloKey]() -> std::optional<response::StringType>
{
std::cout << "Called getHelloMsg..." << std::endl;
return std::optional<response::StringType>();
}
);
auto service = std::make_shared<hello::Operations>(query);
std::cout << "Created the service..." << std::endl;
try
{
peg::ast query;
if (argc > 1)
{
query = peg::parseFile(argv[1]);
}
else
{
std::istream_iterator<char> start{std::cin >> std::noskipws}, end{};
std::string input{start, end};
query = peg::parseString(std::move(input));
}
if (!query.root)
{
std::cerr << "Unknown error!" << std::endl;
std::cerr << std::endl;
return 1;
}
std::cout << "Executing query..." << std::endl;
std::cout << response::toJSON(service
->resolve(nullptr,
query,
((argc > 2) ? argv[2] : ""),
response::Value(response::Type::Map))
.get())
<< std::endl;
}
catch (const std::runtime_error &ex)
{
std::cerr << ex.what() << std::endl;
return 1;
}
return 0;
}
NodeJS program:
var express = require('express');
var {
graphqlHTTP
} = require('express-graphql');
var {
buildSchema
} = require('graphql');
var schema = buildSchema(`
type Query {
hello: String
}
`);
var root = {
hello: () => 'Hello world!'
};
var app = express();
app.use('/graphql', graphqlHTTP({
schema: schema,
rootValue: root,
graphiql: true,
}));
app.listen(4000, () => console.log('Now browse to localhost:4000/graphql'));
If there is a way to use flat files in GraphQL API services. Please Let me know. I want to eagerly write a Newer implementation with GraphQL API for my project. And how to use and implement node addon in the second clientgen Service? What is the use of clientgen? Please help me.
We've been discussing this in https://github.com/microsoft/cppgraphqlgen/issues/191, and I think most of the build problems have been sorted out.
One thing we haven't talked about there is the purpose of clientgen in https://github.com/microsoft/cppgraphqlgen. This is for generating compiled GraphQL queries, in case you want to call a GraphQL service from C++. You probably don't need to worry about this for your scenario, since you're talking about exposing a GraphQL service from a flat file. If you have C or C++ APIs for accessing the files, schemagen (and the graphqlservice/graphqlintrospection libraries) should be all you need.
Context
I have been working with C++ for about the past 5-6 months and I'm beginning to learn gRPC. I have followed many tutorials online to get started, but I want to build a client-server communication app from scratch. Probably a bit too much, but I'm doing my best to understand how to get it all to work from the ground up rather than downloading, typing 'make', and then having a working product that I don't know how to implement into my own projects.
Goal: Create and run a simple C++ gRPC client-server communication
Versions
Using VSCode IDE.
Protoc = libprotoc 3.17.3
gRPC = 1.41.1
make = 3.81
Files
mathtest.proto
syntax = "proto3";
option java_package = "ex.grpc";
package mathtest;
// Defines the service
service MathTest {
// Function invoked to send the request
rpc sendRequest (MathRequest) returns (MathReply) {}
}
// The request message containing requested numbers
message MathRequest {
int32 a = 1;
int32 b = 2;
}
// The response message containing response
message MathReply {
int32 result = 1;
}
server.cpp
#include <string>
#include <grpcpp/grpcpp.h>
#include "mathtest.grpc.pb.h"
using grpc::Server;
using grpc::ServerBuilder;
using grpc::ServerContext;
using grpc::Status;
using mathtest::MathTest;
using mathtest::MathRequest;
using mathtest::MathReply;
class MathServiceImplementation final : public MathTest::Service {
Status sendRequest(
ServerContext* context,
const MathRequest* request,
MathReply* reply
) override {
int a = request->a();
int b = request->b();
reply->set_result(a * b);
return Status::OK;
}
};
void Run() {
std::string address("0.0.0.0:5000");
MathServiceImplementation service;
ServerBuilder builder;
builder.AddListeningPort(address, grpc::InsecureServerCredentials());
builder.RegisterService(&service);
std::unique_ptr<Server> server(builder.BuildAndStart());
std::cout << "Server listening on port: " << address << std::endl;
server->Wait();
}
int main(int argc, char** argv) {
Run();
return 0;
}
client.cpp
#include <string>
#include <grpcpp/grpcpp.h>
#include "mathtest.grpc.pb.h"
using grpc::Channel;
using grpc::ClientContext;
using grpc::Status;
using mathtest::MathTest;
using mathtest::MathRequest;
using mathtest::MathReply;
class MathTestClient {
public:
MathTestClient(std::shared_ptr<Channel> channel) : stub_(MathTest::NewStub(channel)) {}
int sendRequest(int a, int b) {
MathRequest request;
request.set_a(a);
request.set_b(b);
MathReply reply;
ClientContext context;
Status status = stub_->sendRequest(&context, request, &reply);
if(status.ok()){
return reply.result();
} else {
std::cout << status.error_code() << ": " << status.error_message() << std::endl;
return -1;
}
}
private:
std::unique_ptr<MathTest::Stub> stub_;
};
void Run() {
std::string address("0.0.0.0:5000");
MathTestClient client(
grpc::CreateChannel(
address,
grpc::InsecureChannelCredentials()
)
);
int response;
int a = 5;
int b = 10;
response = client.sendRequest(a, b);
std::cout << "Answer received: " << a << " * " << b << " = " << response << std::endl;
}
int main(int argc, char* argv[]){
Run();
return 0;
}
Steps taken for compilation
Use mathtest.proto to create the necessary files via 'protoc' (or protobuf) by executing these: protoc --grpc_out=. --plugin=protoc-gen-grpc=/opt/homebrew/bin/grpc_cpp_plugin mathtest.proto & protoc --cpp_out=. mathtest.proto
This creates the following files:
mathtest.pb.h
mathtest.pb.cc
mathtest.grpc.pb.h
mathtest.grpc.pb.cc
Compile client.cpp & server.cpp files to create executable binaries using these commands: g++ -std=c++17 client.cpp mathtest.pb.cc mathtest.grpc.pb.cc -o client 'pkg-config --libs protobuf grpc++' (NOTE: in this post, I use a single quote in the command line, but in the actual command I use a backtick; just wanted to make that clear)
Errors
As you may notice, I can't get to compiling the server because I can't get past the client compilation first. After executing the above command in step 2 of compilation, this is my output:
g++ -std=c++17 client.cpp mathtest.pb.cc mathtest.grpc.pb.cc -o client `pkg-config --libs protobuf grpc++`
client.cpp:4:10: fatal error: 'grpcpp/grpcpp.h' file not found
#include <grpcpp/grpcpp.h>
^~~~~~~~~~~~~~~~~
1 error generated.
In file included from mathtest.pb.cc:4:
./mathtest.pb.h:10:10: fatal error: 'google/protobuf/port_def.inc' file not found
#include <google/protobuf/port_def.inc>
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 error generated.
In file included from mathtest.grpc.pb.cc:5:
./mathtest.pb.h:10:10: fatal error: 'google/protobuf/port_def.inc' file not found
#include <google/protobuf/port_def.inc>
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 error generated.
make: *** [client] Error 1
Here's my real confusion...
C++ intellisense has no issues finding these files. My $PATH variables point to these folders, and my VS Code include path also point to these folders. I'm unsure where I am going wrong here...
echo $PATH returns this:
/opt/homebrew/bin:/opt/homebrew/sbin:/opt/homebrew/include:/opt/homebrew/Cellar:/opt/homebrew/opt/libtool/libexec/gnubin:/usr/bin:/bin:/usr/sbin:/sbin:/Users/tzeller/.local/bin
The folders in question ('google' & 'grcpp') live within /opt/homebrew/include and they hold the necessary files as well...
What am I missing??
Change your compile command to
g++ -std=c++17 client.cpp mathtest.pb.cc mathtest.grpc.pb.cc -o client `pkg-config --libs --cflags protobuf grpc++`
The --cflags bit asks pkg-config to spit out the necessary parameters for setting the header search path (on my system -I/opt/homebrew/Cellar/grpc/1.41.1/include and others)
Accessing IIS webservice using Gsoap.
I have similar error as in this link shows that the error was solved compiling with -lssl.
I did the same thing in build as
g++ -o client client.cpp stdsoap2.cpp soapC.cpp soapDataManagementSoapProxy.cpp -I /usr/local/ssl/include -L/home/xavier/GSOAP/lib -lgsoapssl++ -L/usr/local/ssl/lib -lssl
My GSOAP lib was build with OpenSSL.
But I still have error as
SOAP 1.2 fault SOAP-ENV:Sender[no subcode]
"OpenSSL not installed: recompile with -DWITH_OPENSSL"
Detail: [no detail]
My test code is as follow. What could be wrong?
#include "soapDataManagementSoapProxy.h"
#include "DataManagementSoap.nsmap"
const char server[] = "https://XXXXXXX.com/XXXmanagement.asmx";
int main(int argc, char **argv)
{
DataManagementSoapProxy webinf;
webinf.soap_endpoint = server;
_tempuri__ReadTestData* a;
_tempuri__ReadTestDataResponse res;
int ret = webinf.ReadTestData(a, res);
if (webinf.error){
webinf.soap_stream_fault(std::cerr);
}
else{
//printf("result = %g\n", result);
std::cout << "Success " << std::endl;
}
webinf.destroy(); /* clean up mem */
return 0;
}
Solution for this issue is
#include "calc.nsmap"
#include "soapcalcProxy.h" // generated with soapcpp2 -j calc.h
calcProxy calc("https-server-endpoint-URL");
double sum;
soap_ssl_init(); // init SSL (just need to do this once in an application)
// soap_ssl_no_init(); // or prevent init OpenSSL when already initialized elsewhere in an application
if (soap_ssl_client_context(calc.soap,
SOAP_SSL_DEFAULT,
NULL, // no keyfile
NULL, // no keyfile password
"cacerts.pem", // trusted certificates (or use self-signed cacert.pem)
NULL, // no capath to trusted certificates
NULL // no random data to seed randomness
))
{
calc.soap_stream_fault(std::cerr);
exit(EXIT_FAILURE);
}
if (calc.add(1.23, 4.56, sum) == SOAP_OK)
Both tools are available over here: https://github.com/ninjablocks/433Utils/tree/master/RPi_utils
I really want a simple interface to manage my 433mhz devices. but i can't find a good one.
So I have worked all day now trying to make a wrapper for nodejs to the RCSwitch class. with 2 simple methods
- send[code]
- recieve[callback[code]]
I get this error when i try to make a new instance of the RCSwitch class.
node: symbol lookup error:
/root/nodemodule/example/build/Release/kaku.node:
undefined symbol: _ZN8RCSwitchC1Ev
It compiles perfectly with node-gyp but when I execute node it fails.
Now I use exec to execute sendCommand with the code. (UGLY I Know)
And I tried to make the RFSniffer work like this:
./RFSniffer > rfsniffer.log
.Then tail -f the rfsniffer.log
But RFSniffer wont give me any data.
So my question is can anybody help me to get RFsniffer working with tail -f
Or even beter can someone help me fix the c++ addon for nodejs:)
Here is the wrapper code:
#include "RCSwitch.h"
#include <node.h>
#include <v8.h>
using namespace v8;
Handle<Value> CodeSend(const Arguments& args) {
HandleScope scope;
int PIN = 0;
RCSwitch mySwitch = RCSwitch();
mySwitch.enableTransmit(PIN);
mySwitch.send(args[0]->IntegerValue(), 24);
return scope.Close(True());
}
Handle<Value> CodeRecieve(const Arguments& args) {
HandleScope scope;
// Entry check
if (args.Length() != 2) {
ThrowException(Exception::TypeError(String::New("Wrong number of arguments")));
return scope.Close(Undefined());
}
Local<String> name= args[0]->ToString();
Local<String> msg = name;
Local<Function> cb = Local<Function>::Cast(args[1]);
const unsigned argc = 1;
Local<Value> argv[argc] = { Local<Value>::New(msg) };
cb->Call(Context::GetCurrent()->Global(), argc, argv);
return scope.Close(Undefined());
}
extern "C" {
static void init(Handle<Object> target) {
if( wiringPiSetup() == -1 ) {
ThrowException( Exception::TypeError( String::New( "rcswitch: GPIO initialization failed" ) ) );
return;
}
NODE_SET_METHOD(target, "Send", CodeSend);
NODE_SET_METHOD(target, "Recieve", CodeRecieve);
}
NODE_MODULE(kaku, init);
}
nodejs code:
var addon = require('./build/Release/kaku');
console.log(addon.Send(1234));
addon.Recieve(1234, function (val) {
console.log(val);
});
I had the same problem than you and the reason why ./RFSniffer > rfsniffer.log doesn't work is that printf() function in RFSniffer code is not flushed.
Try with this source code :
/*
RF_Sniffer
Hacked from http://code.google.com/p/rc-switch/
by #justy to provide a handy RF code sniffer
*/
#include "RCSwitch.h"
#include <stdlib.h>
#include <stdio.h>
RCSwitch mySwitch;
int main(int argc, char *argv[]) {
// This pin is not the first pin on the RPi GPIO header!
// Consult https://projects.drogon.net/raspberry-pi/wiringpi/pins/
// for more information.
int PIN = 2;
if(wiringPiSetup() == -1)
return 0;
mySwitch = RCSwitch();
mySwitch.enableReceive(PIN); // Receiver on inerrupt 0 => that is pin #2
while(1) {
if (mySwitch.available()) {
int value = mySwitch.getReceivedValue();
if (value == 0) {
printf("Unknown encoding");
} else {
printf("Received %i\n", mySwitch.getReceivedValue() );
}
fflush(stdout); // Add this line to flush the previous printf()
mySwitch.resetAvailable();
}
}
exit(0);
}
And if you run the RFSniffer tool with sudo permission, you can execute with :
sudo ./RFSniffer | sudo tee rfsniffer.log
OR
sudo sh -c './RFSniffer >> rfsniffer.log'
I have just started a development using wt(with c++ binding). And i have could done till now, is reading a very few documentation and a little no of sample programs(written in c++ and wt).
After that I installed wt on my machine amd tried to run one one of those demo programs.
hello.cc
#include <Wt/WApplication>
#include <Wt/WBreak>
#include <Wt/WContainerWidget>
#include <Wt/WLineEdit>
#include <Wt/WPushButton>
#include <Wt/WText>
class HelloApplication : public Wt::WApplication
{
public:
HelloApplication(const Wt::WEnvironment& env);
private:
Wt::WLineEdit *nameEdit_;
Wt::WText *greeting_;
void greet();
};
HelloApplication::HelloApplication(const Wt::WEnvironment& env)
: Wt::WApplication(env)
{
setTitle("Hello world");
root()->addWidget(new Wt::WText("Your name, please ? "));
nameEdit_ = new Wt::WLineEdit(root());
Wt::WPushButton *button = new Wt::WPushButton("Greet me.", root());
root()->addWidget(new Wt::WBreak());
greeting_ = new Wt::WText(root());
button->clicked().connect(this, &HelloApplication::greet);
}
void HelloApplication::greet()
{
greeting_->setText("Hello there, " + nameEdit_->text());
}
Wt::WApplication *createApplication(const Wt::WEnvironment& env)
{
return new HelloApplication(env);
}
int main(int argc, char **argv)
{
return Wt::WRun(argc, argv, &createApplication);
}
I complied this code
g++ -o hello hello.cc -lwthttp -lwt
It was compiled successfully.Then I could run this server application successfully to run it on localhost
[manmatha#manmatha Lab]$ su
Password:
[root#manmatha Lab]# ./hello --docroot . --http-address 127.0.0.1 --http-port 9090
[2013-Jun-14 13:58:08.585419] 5066-[info] "WServer/wthttp:initializing built-in wthttpd"
[2013-Jun-14 13:58:08.590955] 5066-[info] "wthttp:started server: http://127.0.0.1:9090"
problem is when I type
localhost::9090
on the address bar of the internet browser on local machine., anything does not show up.
In this context , my specific question is how to start a wt client??
Thanx in advannce
try 127.0.0.1:9090
You specified 127.0.0.1 on the command line so type it in the browser's address bar.
This is a specific of the Wt embedded http server.
You have to mention the --deploy-path variable in your command line arguments. Try this
--http-address 127.0.0.1 --http-port 9090 --deploy-path=/hello --docroot=.
In the browser type http://localhost:9090/hello