c++使用rabbitmq

RabbitmqClient.h

#pragma once


#include <string>

#include "amqp_tcp_socket.h"

using std::string;
//using std::vector;

class CRabbitmqClient {
public:
    CRabbitmqClient();
    ~CRabbitmqClient();


    int Connect(const string &strHostname, int iPort, const string &strUser, const string &strPasswd);
    int Disconnect();

    /**
    *   @brief       ExchangeDeclare    聲明exchange
    *   @param       [in]               strExchange
    *   @param       [in]               strType
    *   @return 等于0值代表成功創(chuàng)建exchange烦绳,小于0代表錯(cuò)誤
    */
    int ExchangeDeclare(const string &strExchange, const string &strType);

    /**
    *   @brief       QueueDeclare                     聲明消息隊(duì)列
    *   @param       [in]               strQueueName  消息隊(duì)列實(shí)例
    *   @param
    *   @return 等于0值代表成功創(chuàng)建queue恒削,小于0代表錯(cuò)誤
    */
    int QueueDeclare(const string &strQueueName);

    /**
    *   @brief       QueueBind                        將隊(duì)列歉眷,交換機(jī)和綁定規(guī)則綁定起來(lái)形成一個(gè)路由表
    *   @param       [in]               strQueueName  消息隊(duì)列
    *   @param       [in]               strExchange   交換機(jī)名稱(chēng)
    *   @param       [in]               strBindKey    路由名稱(chēng)  “msg.#” “msg.weather.**”
    *   @return 等于0值代表成功綁定,小于0代表錯(cuò)誤
    */
    int QueueBind(const string &strQueueName, const string &strExchange, const string &strBindKey);

    /**
    *   @brief       QueueUnbind                      將隊(duì)列戴陡,交換機(jī)和綁定規(guī)則綁定解除
    *   @param       [in]               strQueueName  消息隊(duì)列
    *   @param       [in]               strExchange   交換機(jī)名稱(chēng)
    *   @param       [in]               strBindKey    路由名稱(chēng)  “msg.#” “msg.weather.**”
    *   @return 等于0值代表成功綁定褂萧,小于0代表錯(cuò)誤
    */
    int QueueUnbind(const string &strQueueName, const string &strExchange, const string &strBindKey);

    /**
    *   @brief       QueueDelete                      刪除消息隊(duì)列。
    *   @param       [in]               strQueueName  消息隊(duì)列名稱(chēng)
    *   @param       [in]               iIfUnused     消息隊(duì)列是否在用嫂冻,1 則論是否在用都刪除
    *   @return 等于0值代表成功刪除queue胶征,小于0代表錯(cuò)誤
    */
    int QueueDelete(const string &strQueueName, int iIfUnused);

    /**
    * @brief Publish  發(fā)布消息
    * @param [in] strMessage        消息實(shí)體
    * @param [in] strExchange       交換器
    * @param [in] strRoutekey       路由規(guī)則
    *   1.Direct Exchange – 處理路由鍵。需要將一個(gè)隊(duì)列綁定到交換機(jī)上桨仿,要求該消息與一個(gè)特定的路由鍵完全匹配睛低。
    *   2.Fanout Exchange – 不處理路由鍵。將隊(duì)列綁定到交換機(jī)上服傍。一個(gè)發(fā)送到交換機(jī)的消息都會(huì)被轉(zhuǎn)發(fā)到與該交換機(jī)綁定的所有隊(duì)列上钱雷。
    *   3.Topic Exchange – 將路由鍵和某模式進(jìn)行匹配。此時(shí)隊(duì)列需要綁定要一個(gè)模式上吹零。符號(hào)“#”匹配一個(gè)或多個(gè)詞罩抗,符號(hào)“*”匹配不多不少一個(gè)詞。
    *      因此“audit.#”能夠匹配到“audit.irs.corporate”灿椅,但是“audit.*” 只會(huì)匹配到“audit.irs”
    * @return 等于0值代表成功發(fā)送消息實(shí)體套蒂,小于0代表發(fā)送錯(cuò)誤
    */
    int Publish(const string &strMessage, const string &strExchange, const string &strRoutekey);

    /**
    * @brief consumer  消費(fèi)消息
    * @param [in]  strQueueName         隊(duì)列名稱(chēng)
    * @param [out] message_array        獲取的消息實(shí)體
    * @param [int] GetNum               需要取得的消息個(gè)數(shù)
    * @param [int] timeout              取得的消息是延遲,若為NULL茫蛹,表示持續(xù)取操刀,無(wú)延遲,阻塞狀態(tài)
    * @return 等于0值代表成功婴洼,小于0代表錯(cuò)誤骨坑,錯(cuò)誤信息從ErrorReturn返回
    */
    int Consumer(const string &strQueueName, string &message_array, int GetNum = 1, struct timeval *timeout = NULL);


private:
    CRabbitmqClient(const CRabbitmqClient & rh);
    void operator=(const CRabbitmqClient & rh);

    int ErrorMsg(amqp_rpc_reply_t x, char const *context);


    string                      m_strHostname;      // amqp主機(jī)
    int                         m_iPort;            // amqp端口
    string                      m_strUser;
    string                      m_strPasswd;
    int                         m_iChannel;

    amqp_socket_t               *m_pSock;
    amqp_connection_state_t     m_pConn;
};

RabbitmqClient.cpp

#include "RabbitmqClient.h"



#include "RabbitmqClient.h"
#include <io.h>
#include <process.h>


CRabbitmqClient::CRabbitmqClient()
    : m_strHostname("")
    , m_iPort(0)
    , m_strUser("")
    , m_strPasswd("")
    , m_iChannel(1) //默認(rèn)用1號(hào)通道,通道無(wú)所謂 
    , m_pSock(NULL)
    , m_pConn(NULL) {

}

CRabbitmqClient::~CRabbitmqClient() {
    if (NULL != m_pConn) {
        Disconnect();
        m_pConn = NULL;
    }
}

int CRabbitmqClient::Connect(const string &strHostname, int iPort, const string &strUser, const string &strPasswd) {
    m_strHostname = strHostname;
    m_iPort = iPort;
    m_strUser = strUser;
    m_strPasswd = strPasswd;

    m_pConn = amqp_new_connection();  //返回連接狀態(tài)的指針
    if (NULL == m_pConn) {
        fprintf(stderr, "amqp new connection failed\n");
        return -1;
    }

    m_pSock = amqp_tcp_socket_new(m_pConn); //創(chuàng)建一個(gè)tcp套接字
    if (NULL == m_pSock) {
        fprintf(stderr, "amqp tcp new socket failed\n");
        return -2;
    }

    int status = amqp_socket_open(m_pSock, m_strHostname.c_str(), m_iPort);  //綁定ip和端口打開(kāi)一個(gè)連接
    if (status<0) {
        fprintf(stderr, "amqp socket open failed\n");
        return -3;
    }

    // amqp_login(amqp_connection_state_t state,char const *vhost, int channel_max, int frame_max, int heartbeat, amqp_sasl_method_enum sasl_method, ..)
    if (0 != ErrorMsg(amqp_login(m_pConn, "/", 0, 131072, 0, AMQP_SASL_METHOD_PLAIN, m_strUser.c_str(), m_strPasswd.c_str()), "Logging in")) //用戶(hù)名和密碼登錄mq
    {
        return -4;
    }

    return 0;
}

int CRabbitmqClient::Disconnect() {
    if (NULL != m_pConn) {
        if (0 != ErrorMsg(amqp_connection_close(m_pConn, AMQP_REPLY_SUCCESS), "Closing connection"))
            return -1;

        if (amqp_destroy_connection(m_pConn) < 0)
            return -2;

        m_pConn = NULL;
    }

    return 0;
}

int CRabbitmqClient::ExchangeDeclare(const string &strExchange, const string &strType) {
    amqp_channel_open(m_pConn, m_iChannel);

    amqp_bytes_t _exchange = amqp_cstring_bytes(strExchange.c_str());
    amqp_bytes_t _type = amqp_cstring_bytes(strType.c_str());
    int _passive = 0;
    int _durable = 0;      // 交換機(jī)是否持久化
    amqp_exchange_declare(m_pConn, m_iChannel, _exchange, _type, _passive, _durable, 0, 0, amqp_empty_table);
    if (0 != ErrorMsg(amqp_get_rpc_reply(m_pConn), "exchange_declare")) {
        amqp_channel_close(m_pConn, m_iChannel, AMQP_REPLY_SUCCESS);
        return -1;
    }

    amqp_channel_close(m_pConn, m_iChannel, AMQP_REPLY_SUCCESS);
    return 0;
}

int CRabbitmqClient::QueueDeclare(const string &strQueueName) {
    if (NULL == m_pConn) {
        fprintf(stderr, "QueueDeclare m_pConn is null\n");
        return -1;
    }

    amqp_channel_open(m_pConn, m_iChannel);
    amqp_bytes_t _queue = amqp_cstring_bytes(strQueueName.c_str());
    int32_t _passive = 0;
    int32_t _durable = 0;
    int32_t _exclusive = 0;
    int32_t _auto_delete = 1;
    amqp_queue_declare(m_pConn, m_iChannel, _queue, _passive, _durable, _exclusive, _auto_delete, amqp_empty_table);
    if (0 != ErrorMsg(amqp_get_rpc_reply(m_pConn), "queue_declare")) {
        amqp_channel_close(m_pConn, m_iChannel, AMQP_REPLY_SUCCESS);
        return -1;
    }

    amqp_channel_close(m_pConn, m_iChannel, AMQP_REPLY_SUCCESS);
    return 0;
}

int CRabbitmqClient::QueueBind(const string &strQueueName, const string &strExchange, const string &strBindKey) {
    if (NULL == m_pConn) {
        fprintf(stderr, "QueueBind m_pConn is null\n");
        return -1;
    }

    amqp_channel_open(m_pConn, m_iChannel);
    amqp_bytes_t _queue = amqp_cstring_bytes(strQueueName.c_str());
    amqp_bytes_t _exchange = amqp_cstring_bytes(strExchange.c_str());
    amqp_bytes_t _routkey = amqp_cstring_bytes(strBindKey.c_str());
    amqp_queue_bind(m_pConn, m_iChannel, _queue, _exchange, _routkey, amqp_empty_table);
    if (0 != ErrorMsg(amqp_get_rpc_reply(m_pConn), "queue_bind")) {
        amqp_channel_close(m_pConn, m_iChannel, AMQP_REPLY_SUCCESS);
        return -1;
    }

    amqp_channel_close(m_pConn, m_iChannel, AMQP_REPLY_SUCCESS);
    return 0;
}

int CRabbitmqClient::QueueUnbind(const string &strQueueName, const string &strExchange, const string &strBindKey) {
    if (NULL == m_pConn) {
        fprintf(stderr, "QueueUnbind m_pConn is null\n");
        return -1;
    }

    amqp_channel_open(m_pConn, m_iChannel);
    amqp_bytes_t _queue = amqp_cstring_bytes(strQueueName.c_str());
    amqp_bytes_t _exchange = amqp_cstring_bytes(strExchange.c_str());
    amqp_bytes_t _routkey = amqp_cstring_bytes(strBindKey.c_str());
    amqp_queue_unbind(m_pConn, m_iChannel, _queue, _exchange, _routkey, amqp_empty_table);
    if (0 != ErrorMsg(amqp_get_rpc_reply(m_pConn), "queue_unbind")) {
        amqp_channel_close(m_pConn, m_iChannel, AMQP_REPLY_SUCCESS);
        return -1;
    }

    amqp_channel_close(m_pConn, m_iChannel, AMQP_REPLY_SUCCESS);
    return 0;
}

int CRabbitmqClient::QueueDelete(const string &strQueueName, int iIfUnused) {
    if (NULL == m_pConn) {
        fprintf(stderr, "QueueDelete m_pConn is null\n");
        return -1;
    }

    amqp_channel_open(m_pConn, m_iChannel);
    if (0 != ErrorMsg(amqp_get_rpc_reply(m_pConn), "open channel")) {
        amqp_channel_close(m_pConn, m_iChannel, AMQP_REPLY_SUCCESS);
        return -2;
    }

    amqp_queue_delete(m_pConn, m_iChannel, amqp_cstring_bytes(strQueueName.c_str()), iIfUnused, 0);
    if (0 != ErrorMsg(amqp_get_rpc_reply(m_pConn), "delete queue")) {
        amqp_channel_close(m_pConn, m_iChannel, AMQP_REPLY_SUCCESS);
        return -3;
    }

    amqp_channel_close(m_pConn, m_iChannel, AMQP_REPLY_SUCCESS);
    return 0;
}

int CRabbitmqClient::Publish(const string &strMessage, const string &strExchange, const string &strRoutekey) {
    if (NULL == m_pConn) {
        fprintf(stderr, "publish m_pConn is null, publish failed\n");
        return -1;
    }

    amqp_channel_open(m_pConn, m_iChannel);
    if (0 != ErrorMsg(amqp_get_rpc_reply(m_pConn), "open channel")) {
        amqp_channel_close(m_pConn, m_iChannel, AMQP_REPLY_SUCCESS);
        return -2;
    }

    amqp_bytes_t message_bytes;
    message_bytes.len = strMessage.length();
    message_bytes.bytes = (void *)(strMessage.c_str());
    //fprintf(stderr, "publish message(%d): %.*s\n", (int)message_bytes.len, (int)message_bytes.len, (char *)message_bytes.bytes);

    /*
    amqp_basic_properties_t props;
    props._flags = AMQP_BASIC_CONTENT_TYPE_FLAG | AMQP_BASIC_DELIVERY_MODE_FLAG;
    props.content_type = amqp_cstring_bytes(m_type.c_str());
    props.delivery_mode = m_durable;    // persistent delivery mode
    */

    amqp_bytes_t exchange = amqp_cstring_bytes(strExchange.c_str());
    amqp_bytes_t routekey = amqp_cstring_bytes(strRoutekey.c_str());

    //if (0 != amqp_basic_publish(m_pConn, m_iChannel, exchange, routekey, 0, 0, &props, message_bytes)) {
    if (0 != amqp_basic_publish(m_pConn, m_iChannel, exchange, routekey, 0, 0, NULL, message_bytes)) {
        fprintf(stderr, "publish amqp_basic_publish failed\n");
        if (0 != ErrorMsg(amqp_get_rpc_reply(m_pConn), "amqp_basic_publish")) {
            amqp_channel_close(m_pConn, m_iChannel, AMQP_REPLY_SUCCESS);
            return -3;
        }
    }

    amqp_channel_close(m_pConn, m_iChannel, AMQP_REPLY_SUCCESS);
    return 0;
}

bool bhave = false;

int CRabbitmqClient::Consumer(const string &strQueueName, string &message_array, int GetNum, struct timeval *timeout) {
    if (NULL == m_pConn) 
    {
        fprintf(stderr, "Consumer m_pConn is null, Consumer failed\n");
        return -1;
    }

    amqp_channel_open(m_pConn, m_iChannel);  //打開(kāi)信道
    if (0 != ErrorMsg(amqp_get_rpc_reply(m_pConn), "open channel"))  //返回打開(kāi)信道的結(jié)果
    {
        amqp_channel_close(m_pConn, m_iChannel, AMQP_REPLY_SUCCESS);
        return -2;
    }

    amqp_basic_qos(m_pConn, m_iChannel, 0, GetNum, 0);
    int ack = 1; // no_ack    是否需要確認(rèn)消息后再?gòu)年?duì)列中刪除消息
    amqp_bytes_t queuename = amqp_cstring_bytes(strQueueName.c_str());  //將c字符串轉(zhuǎn)為amap_bytes_t類(lèi)型的字符串
    amqp_basic_consume(m_pConn, m_iChannel, queuename, amqp_empty_bytes, 0, ack, 0, amqp_empty_table);

    if (0 != ErrorMsg(amqp_get_rpc_reply(m_pConn), "Consuming")) {
        amqp_channel_close(m_pConn, m_iChannel, AMQP_REPLY_SUCCESS);
        return -3;
    }

    int hasget = 0;
    
    
    
    while (1) 
    {
        amqp_rpc_reply_t res;
        amqp_envelope_t envelope;
        amqp_maybe_release_buffers(m_pConn);

        res = amqp_consume_message(m_pConn, &envelope, timeout, 0);
        if (AMQP_RESPONSE_NORMAL != res.reply_type) 
        {
            /*fprintf(stderr, "Consumer amqp_channel_close failed\n");
            amqp_channel_close(m_pConn, m_iChannel, AMQP_REPLY_SUCCESS);

            if (0 == hasget)
                return -res.reply_type;
            else
                return 0;*/
            continue;
        }

        string str((char *)envelope.message.body.bytes, (char *)envelope.message.body.bytes + envelope.message.body.len);
        message_array = str;
        //int rtn = amqp_basic_ack(m_pConn, m_iChannel, envelope.delivery_tag, 1);


        amqp_destroy_envelope(&envelope);
        /*if (rtn != 0)
        {
            
            amqp_channel_close(m_pConn, m_iChannel, AMQP_REPLY_SUCCESS);
            return -4;
        }*/

        bhave = true;
        //GetNum--;
        //hasget++;
        //usleep(1);
    }

    return 0;
}

int CRabbitmqClient::ErrorMsg(amqp_rpc_reply_t x, char const *context) {
    switch (x.reply_type) {
    case AMQP_RESPONSE_NORMAL:
        return 0;

    case AMQP_RESPONSE_NONE:
        fprintf(stderr, "%s: missing RPC reply type!\n", context);
        break;

    case AMQP_RESPONSE_LIBRARY_EXCEPTION:
        fprintf(stderr, "%s: %s\n", context, amqp_error_string2(x.library_error));
        break;

    case AMQP_RESPONSE_SERVER_EXCEPTION:
        switch (x.reply.id) {
        case AMQP_CONNECTION_CLOSE_METHOD: {
            amqp_connection_close_t *m = (amqp_connection_close_t *)x.reply.decoded;
            fprintf(stderr, "%s: server connection error %uh, message: %.*s\n",
                context, m->reply_code, (int)m->reply_text.len,
                (char *)m->reply_text.bytes);
            break;
        }
        case AMQP_CHANNEL_CLOSE_METHOD: {
            amqp_channel_close_t *m = (amqp_channel_close_t *)x.reply.decoded;
            fprintf(stderr, "%s: server channel error %uh, message: %.*s\n",
                context, m->reply_code, (int)m->reply_text.len,
                (char *)m->reply_text.bytes);
            break;
        }
        default:
            fprintf(stderr, "%s: unknown server error, method id 0x%08X\n",
                context, x.reply.id);
            break;
        }
        break;
    }

    return -1;
}

main.cpp

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//#include <unistd.h>
#include <iostream>

#include "RabbitmqClient.h"
#include <thread>

using namespace std;

std::string vecRecvMsg;

extern bool bhave;
void RecvData(CRabbitmqClient* client)
{
    std::string strQueuename = "4.3keti";

    
    int iRet = client->Consumer(strQueuename, vecRecvMsg, 1);
    printf("Rabbitmq Consumer Ret: %d\n", iRet);

    

    client->Disconnect();
}

void CoutData()
{
    while (1)
    {
        if (bhave == true)
        {
            
                printf("Consumer: %s\n", vecRecvMsg.c_str());
            

            bhave = false;
        }
        
    }
}

int main()
{
    CRabbitmqClient objRabbitmq;

    std::string strIP = "192.168.10.203";
    int iPort = 5672;
    std::string strUser = "rabbitadmin";
    std::string strPasswd = "123456";


    int iRet = objRabbitmq.Connect(strIP, iPort, strUser, strPasswd);
    printf("Rabbitmq Connect Ret: %d\n", iRet);


    std::string strExchange = "ExchangeTest";
    std::string strRoutekey = "routekeyTest";
    

    //// 可選操作 Declare Exchange
    //iRet = objRabbitmq.ExchangeDeclare(strExchange, "direct");
    //printf("Rabbitmq ExchangeDeclare Ret: %d\n", iRet);

    //// 可選操作(接收) Declare Queue
    //iRet = objRabbitmq.QueueDeclare(strQueuename);
    //printf("Rabbitmq QueueDeclare Ret: %d\n", iRet);

    //// 可選操作(接收) Queue Bind
    //iRet = objRabbitmq.QueueBind(strQueuename, strExchange, strRoutekey);
    //printf("Rabbitmq QueueBind Ret: %d\n", iRet);

    // Send Msg
    //std::string strSendMsg1 = "rabbitmq send test msg1";
    //std::string strSendMsg2 = "rabbitmq send test msg2";
    //iRet = objRabbitmq.Publish(strSendMsg1, strExchange, strRoutekey);
    //printf("Rabbitmq Publish 1 Ret: %d\n", iRet);
    //iRet = objRabbitmq.Publish(strSendMsg2, strExchange, strRoutekey);
    //printf("Rabbitmq Publish 2 Ret: %d\n", iRet);

    // Recv Msg
    

    thread t1(RecvData, &objRabbitmq);
    t1.detach();

    thread t2(CoutData);
    t2.detach();

    while(1)
    {
    }

    return 0;
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末窃蹋,一起剝皮案震驚了整個(gè)濱河市卡啰,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌警没,老刑警劉巖匈辱,帶你破解...
    沈念sama閱讀 222,183評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異杀迹,居然都是意外死亡亡脸,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)浅碾,“玉大人大州,你說(shuō)我怎么就攤上這事〈剐唬” “怎么了厦画?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,766評(píng)論 0 361
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)滥朱。 經(jīng)常有香客問(wèn)我根暑,道長(zhǎng),這世上最難降的妖魔是什么徙邻? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,854評(píng)論 1 299
  • 正文 為了忘掉前任排嫌,我火速辦了婚禮,結(jié)果婚禮上缰犁,老公的妹妹穿的比我還像新娘淳地。我一直安慰自己,他們只是感情好帅容,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,871評(píng)論 6 398
  • 文/花漫 我一把揭開(kāi)白布颇象。 她就那樣靜靜地躺著,像睡著了一般丰嘉。 火紅的嫁衣襯著肌膚如雪夯到。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 52,457評(píng)論 1 311
  • 那天饮亏,我揣著相機(jī)與錄音耍贾,去河邊找鬼。 笑死路幸,一個(gè)胖子當(dāng)著我的面吹牛荐开,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播简肴,決...
    沈念sama閱讀 40,999評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼晃听,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了砰识?” 一聲冷哼從身側(cè)響起能扒,我...
    開(kāi)封第一講書(shū)人閱讀 39,914評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎辫狼,沒(méi)想到半個(gè)月后初斑,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,465評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡膨处,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,543評(píng)論 3 342
  • 正文 我和宋清朗相戀三年见秤,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了砂竖。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,675評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡鹃答,死狀恐怖乎澄,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情测摔,我是刑警寧澤置济,帶...
    沈念sama閱讀 36,354評(píng)論 5 351
  • 正文 年R本政府宣布,位于F島的核電站避咆,受9級(jí)特大地震影響舟肉,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜查库,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,029評(píng)論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望黄琼。 院中可真熱鬧樊销,春花似錦、人聲如沸脏款。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,514評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)撤师。三九已至剂府,卻和暖如春黑滴,著一層夾襖步出監(jiān)牢的瞬間飞主,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,616評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工毒租, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留痒谴,地道東北人衰伯。 一個(gè)月前我還...
    沈念sama閱讀 49,091評(píng)論 3 378
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像积蔚,于是被迫代替她去往敵國(guó)和親意鲸。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,685評(píng)論 2 360

推薦閱讀更多精彩內(nèi)容