Actually pushed across examples

This commit is contained in:
Unknown 2018-03-03 16:08:42 +00:00
parent 13f709aebb
commit 206e421728
3 changed files with 190 additions and 0 deletions

View File

@ -0,0 +1,8 @@
add_executable(simple_websocket_client SimpleWebsocketClient.cpp)
target_link_libraries(simple_websocket_client frnetlib)
add_executable(simple_websocket_server SimpleWebsocketServer.cpp)
target_link_libraries(simple_websocket_server frnetlib)
install(TARGETS simple_websocket_client simple_websocket_server
DESTINATION "bin")

View File

@ -0,0 +1,84 @@
//
// Created by fred on 02/03/18.
//
#include <thread>
#include <iostream>
#include <frnetlib/WebFrame.h>
#include <frnetlib/WebSocket.h>
#include <frnetlib/TcpSocket.h>
int main()
{
//Connect to the WebSocket server
fr::WebSocket<fr::TcpSocket> socket; //Use an fr::SSLSocket for secure connections
if(socket.connect("127.0.0.1", "9091", {}) != fr::Socket::Success)
{
std::cerr << "Failed to connect to server!" << std::endl;
return EXIT_FAILURE;
}
//Loop to send messages. Not ideal due to a lack of locking, but should be okay for an example.
auto message_loop = [&socket]() {
std::string message;
fr::WebFrame frame;
while(socket.connected())
{
std::cout << "Message: " << std::endl;
std::getline(std::cin, message);
if(message == "exit")
{
socket.disconnect();
return;
}
else if(message == "ping")
{
frame.set_opcode(fr::WebFrame::Ping);
}
frame.set_payload(std::move(message));
socket.send(frame);
message.clear(); //Returns message to a defined state after the std::move
}
};
std::thread t1(message_loop);
//Put the socket into non-blocking mode, for dealing with PINGs and whatnot without waiting.
while(socket.connected())
{
//Receive the next frame
fr::WebFrame frame;
if(socket.receive(frame) != fr::Socket::Success)
continue;
//If it's a Ping then we need to send back a frame containing the same payload, but of type Pong.
if(frame.get_opcode() == fr::WebFrame::Ping)
{
std::cout << "Server sent a ping!" << std::endl;
frame.set_opcode(fr::WebFrame::Pong);
socket.send(frame);
continue;
}
//If it's a disconnect message, then we should finish sending across any messages, and then call disconnect
if(frame.get_opcode() == fr::WebFrame::Disconnect)
{
socket.disconnect();
continue;
}
//The payload type could be Text, Binary, or Continuation.
//If it's Continuation, then this frame is a part of a fragmented message, and it's
//a continuation from a previous message. You can check if it's the final part of the
//message using fr::WebFrame::is_final().
std::cout << "Got a new message from the server. It's a ";
if(frame.get_opcode() == fr::WebFrame::Text) std::cout << "text";
else if(frame.get_opcode() == fr::WebFrame::Binary) std::cout << "binary";
else if(frame.get_opcode() == fr::WebFrame::Pong) std::cout << "pong";
else std::cout << "continuation of a previous";
std::cout << " message. It is ";
if(!frame.is_final()) std::cout << "not ";
std::cout << "the final part of the message. The payload contains: '" << frame.get_payload() << "'." << std::endl;
}
std::cout << "The server disconnected!" << std::endl;
t1.join();
}

View File

@ -0,0 +1,98 @@
//
// Created by fred on 02/03/18.
//
#include <iostream>
#include <frnetlib/TcpListener.h>
#include <frnetlib/WebFrame.h>
#include <frnetlib/WebSocket.h>
#include <thread>
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wmissing-noreturn"
int main()
{
//Bind to port, fr::SSLListener should be used for TLS connections
fr::TcpListener listener;
if(listener.listen("9091") != fr::Socket::Success)
{
std::cerr << "Failed to bind to port!" << std::endl;
return EXIT_FAILURE;
}
//Use fr::WebSocket<fr::SSLSocket> if using an SSL listener
fr::WebSocket<fr::TcpSocket> socket;
//Loop to send messages. Not ideal due to a lack of locking, but should be okay for an example.
auto message_loop = [&socket]() {
std::string message;
fr::WebFrame frame;
while(true)
{
frame.set_opcode(fr::WebFrame::Text);
std::cout << "Message: " << std::endl;
std::getline(std::cin, message);
if(message == "exit")
{
socket.disconnect();
return;
}
else if(message == "ping")
{
frame.set_opcode(fr::WebFrame::Ping);
}
frame.set_payload(std::move(message));
socket.send(frame);
message.clear(); //Returns message to a defined state after the std::move
}
};
std::thread t1(message_loop);
while(true)
{
//Accept a new WebSocket connection.
if(listener.accept(socket) != fr::Socket::Success)
continue;
std::cout << "Accepted new connection: " << socket.get_remote_address() << std::endl;
//Whilst we remain connected, keep processing messages
while(socket.connected())
{
//Receive the next frame
fr::WebFrame frame;
if(socket.receive(frame) != fr::Socket::Success)
continue;
//If it's a Ping then we need to send back a frame containing the same payload, but of type Pong.
if(frame.get_opcode() == fr::WebFrame::Ping)
{
std::cout << "Client sent a ping!" << std::endl;
frame.set_opcode(fr::WebFrame::Pong);
socket.send(frame);
continue;
}
//If it's a disconnect message, then we should finish sending across any messages, and then call disconnect
if(frame.get_opcode() == fr::WebFrame::Disconnect)
{
socket.disconnect();
continue;
}
//The payload type could be Text, Binary, or Continuation.
//If it's Continuation, then this frame is a part of a fragmented message, and it's
//a continuation from a previous message. You can check if it's the final part of the
//message using fr::WebFrame::is_final().
std::cout << "Got a new message from the client. It's a ";
if(frame.get_opcode() == fr::WebFrame::Text) std::cout << "text";
else if(frame.get_opcode() == fr::WebFrame::Binary) std::cout << "binary";
else if(frame.get_opcode() == fr::WebFrame::Pong) std::cout << "pong";
else std::cout << "continuation of a previous";
std::cout << " message. It is ";
if(!frame.is_final()) std::cout << "not ";
std::cout << "the final part of the message. The payload contains: '" << frame.get_payload() << "'." << std::endl;
}
std::cout << socket.get_remote_address() << " disconnected!" << std::endl;
}
}
#pragma clang diagnostic pop