websocket client

Fork of WebSocketClient by Samuel Mokrani

Committer:
kanehara
Date:
Sun Jan 31 07:12:25 2016 +0000
Revision:
8:a909ee26be2d
Parent:
6:86e89a0369b9
Child:
9:6275000e9224
bin mode, ping protocol.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kanehara 8:a909ee26be2d 1 /**
kanehara 8:a909ee26be2d 2 * @author Samuel Mokrani
kanehara 8:a909ee26be2d 3 *
kanehara 8:a909ee26be2d 4 * @section LICENSE
kanehara 8:a909ee26be2d 5 *
kanehara 8:a909ee26be2d 6 * Copyright (c) 2011 mbed
kanehara 8:a909ee26be2d 7 *
kanehara 8:a909ee26be2d 8 * Permission is hereby granted, free of charge, to any person obtaining a copy
kanehara 8:a909ee26be2d 9 * of this software and associated documentation files (the "Software"), to deal
kanehara 8:a909ee26be2d 10 * in the Software without restriction, including without limitation the rights
kanehara 8:a909ee26be2d 11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
kanehara 8:a909ee26be2d 12 * copies of the Software, and to permit persons to whom the Software is
kanehara 8:a909ee26be2d 13 * furnished to do so, subject to the following conditions:
kanehara 8:a909ee26be2d 14 *
kanehara 8:a909ee26be2d 15 * The above copyright notice and this permission notice shall be included in
kanehara 8:a909ee26be2d 16 * all copies or substantial portions of the Software.
kanehara 8:a909ee26be2d 17 *
kanehara 8:a909ee26be2d 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
kanehara 8:a909ee26be2d 19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
kanehara 8:a909ee26be2d 20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
kanehara 8:a909ee26be2d 21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
kanehara 8:a909ee26be2d 22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
kanehara 8:a909ee26be2d 23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
kanehara 8:a909ee26be2d 24 * THE SOFTWARE.
kanehara 8:a909ee26be2d 25 *
kanehara 8:a909ee26be2d 26 * @section DESCRIPTION
kanehara 8:a909ee26be2d 27 * Simple websocket client
kanehara 8:a909ee26be2d 28 *
kanehara 8:a909ee26be2d 29 */
kanehara 8:a909ee26be2d 30
kanehara 8:a909ee26be2d 31 #ifndef WEBSOCKET_H
kanehara 8:a909ee26be2d 32 #define WEBSOCKET_H
kanehara 8:a909ee26be2d 33
kanehara 8:a909ee26be2d 34 #include "mbed.h"
kanehara 8:a909ee26be2d 35
kanehara 8:a909ee26be2d 36 #include "TCPSocketConnection.h"
kanehara 8:a909ee26be2d 37
kanehara 8:a909ee26be2d 38 /** Websocket client Class.
kanehara 8:a909ee26be2d 39 *
kanehara 8:a909ee26be2d 40 * Example (ethernet network):
kanehara 8:a909ee26be2d 41 * @code
kanehara 8:a909ee26be2d 42 * #include "mbed.h"
kanehara 8:a909ee26be2d 43 * #include "EthernetInterface.h"
kanehara 8:a909ee26be2d 44 * #include "Websocket.h"
kanehara 8:a909ee26be2d 45 *
kanehara 8:a909ee26be2d 46 * int main() {
kanehara 8:a909ee26be2d 47 * EthernetInterface eth;
kanehara 8:a909ee26be2d 48 * eth.init(); //Use DHCP
kanehara 8:a909ee26be2d 49 * eth.connect();
kanehara 8:a909ee26be2d 50 * printf("IP Address is %s\n\r", eth.getIPAddress());
kanehara 8:a909ee26be2d 51 *
kanehara 8:a909ee26be2d 52 * Websocket ws("ws://sockets.mbed.org:443/ws/demo/rw");
kanehara 8:a909ee26be2d 53 * ws.connect();
kanehara 8:a909ee26be2d 54 *
kanehara 8:a909ee26be2d 55 * while (1) {
kanehara 8:a909ee26be2d 56 * int res = ws.send("WebSocket Hello World!");
kanehara 8:a909ee26be2d 57 *
kanehara 8:a909ee26be2d 58 * if (ws.read(recv)) {
kanehara 8:a909ee26be2d 59 * printf("rcv: %s\r\n", recv);
kanehara 8:a909ee26be2d 60 * }
kanehara 8:a909ee26be2d 61 *
kanehara 8:a909ee26be2d 62 * wait(0.1);
kanehara 8:a909ee26be2d 63 * }
kanehara 8:a909ee26be2d 64 * }
kanehara 8:a909ee26be2d 65 * @endcode
kanehara 8:a909ee26be2d 66 */
kanehara 8:a909ee26be2d 67
kanehara 8:a909ee26be2d 68 class Websocket
kanehara 8:a909ee26be2d 69 {
kanehara 8:a909ee26be2d 70 public:
kanehara 8:a909ee26be2d 71 class MemBuf {
kanehara 8:a909ee26be2d 72 public:
kanehara 8:a909ee26be2d 73 static const int maxsize = 1024; // more than 200
kanehara 8:a909ee26be2d 74 char mem[maxsize];
kanehara 8:a909ee26be2d 75 char* ptr;
kanehara 8:a909ee26be2d 76 ssize_t size;
kanehara 8:a909ee26be2d 77
kanehara 8:a909ee26be2d 78 MemBuf () {
kanehara 8:a909ee26be2d 79 init ();
kanehara 8:a909ee26be2d 80 };
kanehara 8:a909ee26be2d 81 ~MemBuf () {};
kanehara 8:a909ee26be2d 82 void init () {
kanehara 8:a909ee26be2d 83 ptr = mem;
kanehara 8:a909ee26be2d 84 size = 0;
kanehara 8:a909ee26be2d 85 };
kanehara 8:a909ee26be2d 86 size_t alloc (size_t s) {
kanehara 8:a909ee26be2d 87 if (maxsize - (ptr - mem + size) >= s) {
kanehara 8:a909ee26be2d 88 return s;
kanehara 8:a909ee26be2d 89 } else {
kanehara 8:a909ee26be2d 90 memmove (mem, ptr, size);
kanehara 8:a909ee26be2d 91 ptr = mem;
kanehara 8:a909ee26be2d 92 if (maxsize - size >= s) {
kanehara 8:a909ee26be2d 93 return s;
kanehara 8:a909ee26be2d 94 } else {
kanehara 8:a909ee26be2d 95 return maxsize - size;
kanehara 8:a909ee26be2d 96 }
kanehara 8:a909ee26be2d 97 }
kanehara 8:a909ee26be2d 98 };
kanehara 8:a909ee26be2d 99 void skip (size_t s) {
kanehara 8:a909ee26be2d 100 ptr += s;
kanehara 8:a909ee26be2d 101 size -= s;
kanehara 8:a909ee26be2d 102 };
kanehara 8:a909ee26be2d 103 void skipTo (char* p) {
kanehara 8:a909ee26be2d 104 size -= p - ptr;
kanehara 8:a909ee26be2d 105 ptr = p;
kanehara 8:a909ee26be2d 106 };
kanehara 8:a909ee26be2d 107 };
kanehara 8:a909ee26be2d 108
kanehara 8:a909ee26be2d 109 /**
kanehara 8:a909ee26be2d 110 * Constructor
kanehara 8:a909ee26be2d 111 *
kanehara 8:a909ee26be2d 112 * @param url The Websocket url in the form "ws://ip_domain[:port]/path" (by default: port = 80)
kanehara 8:a909ee26be2d 113 */
kanehara 8:a909ee26be2d 114 Websocket(const char * url);
kanehara 8:a909ee26be2d 115 ~Websocket ();
kanehara 8:a909ee26be2d 116
kanehara 8:a909ee26be2d 117 void setFnPing (void (*fn)());
kanehara 8:a909ee26be2d 118
kanehara 8:a909ee26be2d 119 /**
kanehara 8:a909ee26be2d 120 * Connect to the websocket url
kanehara 8:a909ee26be2d 121 *
kanehara 8:a909ee26be2d 122 *@return true if the connection is established, false otherwise
kanehara 8:a909ee26be2d 123 */
kanehara 8:a909ee26be2d 124 bool connect();
kanehara 8:a909ee26be2d 125
kanehara 8:a909ee26be2d 126 /**
kanehara 8:a909ee26be2d 127 * Send a string according to the websocket format (see rfc 6455)
kanehara 8:a909ee26be2d 128 *
kanehara 8:a909ee26be2d 129 * @param str string to be sent
kanehara 8:a909ee26be2d 130 *
kanehara 8:a909ee26be2d 131 * @returns the number of bytes sent
kanehara 8:a909ee26be2d 132 */
kanehara 8:a909ee26be2d 133 int sendOp(uint8_t opcode, size_t len, char* str);
kanehara 8:a909ee26be2d 134 int send(char * str);
kanehara 8:a909ee26be2d 135 int sendBin(size_t len, char* str);
kanehara 8:a909ee26be2d 136
kanehara 8:a909ee26be2d 137 /**
kanehara 8:a909ee26be2d 138 * Read a websocket message
kanehara 8:a909ee26be2d 139 *
kanehara 8:a909ee26be2d 140 * @param message pointer to the string to be read (null if drop frame)
kanehara 8:a909ee26be2d 141 *
kanehara 8:a909ee26be2d 142 * @return true if a websocket frame has been read
kanehara 8:a909ee26be2d 143 */
kanehara 8:a909ee26be2d 144 bool read(char * message, size_t& size);
kanehara 8:a909ee26be2d 145
kanehara 8:a909ee26be2d 146 /**
kanehara 8:a909ee26be2d 147 * To see if there is a websocket connection active
kanehara 8:a909ee26be2d 148 *
kanehara 8:a909ee26be2d 149 * @return true if there is a connection active
kanehara 8:a909ee26be2d 150 */
kanehara 8:a909ee26be2d 151 bool is_connected();
kanehara 8:a909ee26be2d 152
kanehara 8:a909ee26be2d 153 /**
kanehara 8:a909ee26be2d 154 * Close the websocket connection
kanehara 8:a909ee26be2d 155 *
kanehara 8:a909ee26be2d 156 * @return true if the connection has been closed, false otherwise
kanehara 8:a909ee26be2d 157 */
kanehara 8:a909ee26be2d 158 bool close();
kanehara 8:a909ee26be2d 159
kanehara 8:a909ee26be2d 160 /*
kanehara 8:a909ee26be2d 161 * Accessor: get path from the websocket url
kanehara 8:a909ee26be2d 162 *
kanehara 8:a909ee26be2d 163 * @return path
kanehara 8:a909ee26be2d 164 */
kanehara 8:a909ee26be2d 165 char* getPath();
kanehara 8:a909ee26be2d 166
kanehara 8:a909ee26be2d 167 private:
kanehara 8:a909ee26be2d 168
kanehara 8:a909ee26be2d 169 void fillFields(const char * url);
kanehara 8:a909ee26be2d 170 int parseURL(const char* url, char* scheme, size_t maxSchemeLen, char* host, size_t maxHostLen, uint16_t* port, char* path, size_t maxPathLen); //Parse URL
kanehara 8:a909ee26be2d 171 int sendOpcode(uint8_t opcode, char * msg);
kanehara 8:a909ee26be2d 172 int sendLength(uint32_t len, char * msg);
kanehara 8:a909ee26be2d 173 int sendMask(char * msg);
kanehara 8:a909ee26be2d 174 int readChar(char * pC, bool block = true);
kanehara 8:a909ee26be2d 175
kanehara 8:a909ee26be2d 176 char scheme[8];
kanehara 8:a909ee26be2d 177 uint16_t port;
kanehara 8:a909ee26be2d 178 char host[32];
kanehara 8:a909ee26be2d 179 char path[64];
kanehara 8:a909ee26be2d 180 void (*fnPing)();
kanehara 8:a909ee26be2d 181
kanehara 8:a909ee26be2d 182 TCPSocketConnection socket;
kanehara 8:a909ee26be2d 183 MemBuf membuf;
kanehara 8:a909ee26be2d 184
kanehara 8:a909ee26be2d 185 int read(char * buf, int len, int min_len = -1);
kanehara 8:a909ee26be2d 186 int write(char * buf, int len);
kanehara 8:a909ee26be2d 187
kanehara 8:a909ee26be2d 188 uint32_t readLenFrame (char* mask);
kanehara 8:a909ee26be2d 189 bool readBinFrame (char * message, size_t& size);
kanehara 8:a909ee26be2d 190 bool readPing ();
kanehara 8:a909ee26be2d 191 };
kanehara 8:a909ee26be2d 192
kanehara 8:a909ee26be2d 193 #endif