void _ortc_subscribe(ortc_context* context, char* channel, int subscribeOnReconnected, int toBeSaved, void (*onMessage)(ortc_context*, char*, char*)){ char *hash = _ortc_get_channel_permission(context, channel); int len = 16 + strlen(context->appKey) + strlen(context->authToken) + strlen(channel) + strlen(hash); char *subscribeCommand = (char*)malloc(len + 1); if(subscribeCommand == NULL){ _ortc_exception(context, "malloc() failed in ortc subscribe"); return; } subscribeOnReconnected = (subscribeOnReconnected>0)?1:0; if(toBeSaved) _ortc_dlist_insert(context->channels, channel, NULL, NULL, subscribeOnReconnected, (void(*)(ortc_context*, char*, char*))onMessage); snprintf(subscribeCommand, len, "\"subscribe;%s;%s;%s;%s\"", context->appKey, context->authToken, channel, hash); _ortc_send_command(context, subscribeCommand); }
void _ortc_unsubscribe(ortc_context* context, char* channel){ int len = 16 + strlen(context->appKey) + strlen(channel); char *unsubscribeCommand = (char*)malloc(len + 1); ortc_dnode *ch; if(unsubscribeCommand == NULL){ _ortc_exception(context, "malloc() failed in ortc unsubscribe"); return; } ch = _ortc_dlist_search(context->channels, channel); if(ch != NULL) ch->num = -1; //is trying to unsbscribed snprintf(unsubscribeCommand, len, "\"unsubscribe;%s;%s\"", context->appKey, channel); _ortc_send_command(context, unsubscribeCommand); }
void _ortc_parse_message(ortc_context *context, char *message){ char *messageId, *messageCount, *messageTotal, *messagePart, *channelNameStr, *messageStr, *params, *permissionsStr, *exceptionStr, *validateString, *operationType; struct cap pmatch[3], pmatch2[5]; int iMessageTotal, wsSock, opt; size_t len, hbLen; ortc_dnode *ch; char hbStr[24]; if(message[0] == 'a') { if (slre_match(&context->reMessage, message, (int)strlen(message), pmatch)) { //is message channelNameStr = _ortc_get_from_slre(1, pmatch); messageStr = _ortc_get_from_slre(2, pmatch); if(slre_match(&context->reMultipart, messageStr, (int)strlen(messageStr), pmatch2)){ messageId = _ortc_get_from_slre(1, pmatch2); messageCount = _ortc_get_from_slre(2, pmatch2); messageTotal = _ortc_get_from_slre(3, pmatch2); messagePart = _ortc_get_from_slre(4, pmatch2); iMessageTotal = atoi(messageTotal); if(iMessageTotal > 1){ //multipart message _ortc_dlist_insert(context->multiparts, messageId, channelNameStr, messagePart, atoi(messageCount), NULL); _ortc_check_if_got_all_parts(context, messageId, iMessageTotal); } else { _ortc_fire_onMessage(context, channelNameStr, messagePart); } free(messageId); free(messageCount); free(messageTotal); free(messagePart); } else { _ortc_fire_onMessage(context, channelNameStr, messageStr); } free(channelNameStr); free(messageStr); } else if (slre_match(&context->reOperation, message, (int)strlen(message), pmatch)) { params = _ortc_get_from_slre(2, pmatch); operationType = _ortc_get_from_slre(1, pmatch); if(strncmp(operationType, "ortc-validated", 14)==0){ if(slre_match(&context->rePermissions, params, (int)strlen(params), pmatch2)){ permissionsStr = _ortc_get_from_slre(1, pmatch2); _ortc_save_permissions(context, permissionsStr); free(permissionsStr); } _ortc_change_state(context, CONNECTED); } else if(strncmp(operationType, "ortc-subscribed", 15)==0){ if(slre_match(&context->reChannel, params, (int)strlen(params), pmatch2)){ channelNameStr = _ortc_get_from_slre(1, pmatch2); ch = _ortc_dlist_search(context->channels, channelNameStr); if(ch != NULL) ch->num += 2; //isSubscribed if(context->onSubscribed != NULL) context->onSubscribed(context, channelNameStr); free(channelNameStr); } } else if(strncmp(operationType, "ortc-unsubscribed", 17)==0){ if(slre_match(&context->reChannel, params, (int)strlen(params), pmatch2)){ channelNameStr = _ortc_get_from_slre(1, pmatch2); _ortc_dlist_delete(context->channels, channelNameStr); if(context->onUnsubscribed != NULL) context->onUnsubscribed(context, channelNameStr); free(channelNameStr); } } else if(strncmp(operationType, "ortc-error", 10)==0){ if(slre_match(&context->reException, params, (int)strlen(params), pmatch2)){ _ortc_cancel_connecting(context); exceptionStr = _ortc_get_from_slre(1, pmatch2); _ortc_exception(context, exceptionStr); free(exceptionStr); } } free(params); free(operationType); } } else if(message[0] == 'o' && strlen(message)==1){ wsSock = libwebsocket_get_socket_fd(context->wsi); opt = ORTC_SNDBUF_SIZE; setsockopt(wsSock, SOL_SOCKET, SO_SNDBUF, (const char*)&opt, sizeof(opt)); if(context->heartbeatActive){ snprintf(hbStr, sizeof(hbStr), "%d;%d;", context->heartbeatTime, context->heartbeatFails); hbLen = strlen(hbStr); } else { hbLen = 0; } len = 17 + strlen(context->appKey) + strlen(context->authToken) + strlen(context->announcementSubChannel) + strlen(context->sessionId) + strlen(context->metadata) + hbLen; validateString = malloc(len+1); if(validateString == NULL){ _ortc_exception(context, "malloc() failed in ortc parese message"); return; } if(context->heartbeatActive) snprintf(validateString, len, "\"validate;%s;%s;%s;%s;%s;%s\"", context->appKey, context->authToken, context->announcementSubChannel, context->sessionId, context->metadata, hbStr); else snprintf(validateString, len, "\"validate;%s;%s;%s;%s;%s;\"", context->appKey, context->authToken, context->announcementSubChannel, context->sessionId, context->metadata); _ortc_send_command(context, validateString); } else if(strncmp(message, "c[1000,\"Normal closure\"]", 20)==0){ _ortc_exception(context, "Server is about to close the websocket!"); } }