Created
August 9, 2012 20:36
-
-
Save paulbarbu/3307849 to your computer and use it in GitHub Desktop.
SSE in CppCMS
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// Copyright (C) 2008-2012 Artyom Beilis (Tonkikh) <[email protected]> | |
// | |
// See accompanying file COPYING.TXT file for licensing details. | |
// | |
#include <cppcms/application.h> | |
#include <cppcms/url_dispatcher.h> | |
#include <cppcms/applications_pool.h> | |
#include <cppcms/service.h> | |
#include <cppcms/http_response.h> | |
#include <cppcms/http_request.h> | |
#include <cppcms/http_context.h> | |
#include <booster/intrusive_ptr.h> | |
#include <set> | |
#ifdef USE_STD_TR1_BIND | |
#include <tr1/functional> | |
using std::tr1::bind; | |
#elif defined USE_STD_BIND | |
#include <functional> | |
using std::bind; | |
#else | |
#include <boost/bind.hpp> | |
using boost::bind; | |
#endif | |
class chat : public cppcms::application { | |
public: | |
chat(cppcms::service &srv) : cppcms::application(srv) | |
{ | |
dispatcher().assign("/post",&chat::post,this); | |
dispatcher().assign("/get",&chat::get,this); | |
dispatcher().assign(".*",&chat::redirect,this); | |
} | |
void redirect() | |
{ | |
response().set_redirect_header("/the_chat.html"); | |
} | |
void post() | |
{ | |
if(request().request_method()=="POST") { | |
messages_.push_back(request().post("message")); | |
broadcast(); | |
} | |
} | |
void get() | |
{ | |
booster::shared_ptr<cppcms::http::context> context=release_context(); | |
waiters_.insert(context); | |
context->async_on_peer_reset( | |
bind( | |
&chat::remove_context, | |
booster::intrusive_ptr<chat>(this), | |
context)); | |
} | |
void remove_context(booster::shared_ptr<cppcms::http::context> context) | |
{ | |
waiters_.erase(context); | |
std::cerr<<"disco!"<<"\n"; | |
} | |
void get_connection_status(cppcms::http::context::completion_type status,booster::shared_ptr<cppcms::http::context> waiter){ | |
if(status == 0){ | |
std::cerr<<"ok"<<"\n"; | |
// return it back to the set | |
waiters_.insert(waiter); | |
} | |
else{ | |
std::cerr<<"bad!"<<"\n"; | |
} | |
} | |
void broadcast() | |
{ | |
for(waiters_type::iterator it=waiters_.begin();it!=waiters_.end();++it) { | |
booster::shared_ptr<cppcms::http::context> waiter = *it; | |
if(!waiter->response().some_output_was_written()) { | |
waiter->response().set_content_header("text/event-stream"); | |
waiter->response().set_header("Cache-Control", "no-cache"); | |
} | |
waiter->response().out() << "event: message\nretry: 1\ndata: " << | |
messages_.back() << "\n\n"; | |
waiter->response().out() << std::flush; | |
waiter->async_flush_output(boost::bind( | |
&chat::get_connection_status, | |
booster::intrusive_ptr<chat>(this), | |
_1, | |
waiter | |
)); | |
waiters_.erase(waiter); | |
} | |
} | |
private: | |
std::vector<std::string> messages_; | |
typedef std::set<booster::shared_ptr<cppcms::http::context> > waiters_type; | |
waiters_type waiters_; | |
}; | |
int main(int argc,char **argv) | |
{ | |
try { | |
cppcms::service service(argc,argv); | |
booster::intrusive_ptr<chat> c=new chat(service); | |
service.applications_pool().mount(c); | |
service.run(); | |
} | |
catch(std::exception const &e) { | |
std::cerr<<"Catched exception: "<<e.what()<<std::endl; | |
return 1; | |
} | |
return 0; | |
} | |
// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" | |
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> | |
<html> | |
<head> | |
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> | |
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script> | |
<title>Chat Room</title> | |
</head> | |
<body> | |
<h1>Chat room</h1> | |
<script type="text/javascript"> | |
var message_count = 0; | |
function send_data() { | |
$.post("/chat/post", {'message': $('#message').val()}); | |
$("#message").val(""); | |
return false; | |
} | |
function read_data() { | |
var stream = new EventSource('/chat/get'); | |
stream.onmessage = function(e){ | |
$('#messages').html($('#messages').html() + '<br />' + e.data); | |
}; | |
stream.onerror = function(e){ | |
console.log(e); | |
}; | |
} | |
read_data(); | |
</script> | |
<form id="theform" > | |
<input id="message" type="text" name="message" value="" /> | |
<input type="submit" value="Send" onclick="return send_data()"/> | |
</form> | |
<div id="messages"> | |
</div> | |
</body> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment