WebRTC:搭建Socket.Io信令服務(wù)器(實(shí)現(xiàn)簡(jiǎn)單的聊天室)

目錄

效果展示

實(shí)現(xiàn)步驟

1.搭建服務(wù)端

這里我們用的是nodejs搭建的硫惕,由于我們用的不是最新標(biāo)準(zhǔn)的socket.io因此我們需要下載指定版本的socket.io

npm install socket.io@2.0.4

代碼如下:

'use strict'
var http = require('http');
var socketio = require('socket.io');
var server = http.createServer(function(req, res) {
    res.writeHead(200, {'Content-Type': 'text/plain'});
    res.end('Hello World\n');
});
server.listen(3000, '0.0.0.0');
var io = socketio.listen(server);
io.on('connection', (sokcetClient) => {
    console.log(sokcetClient.id);
    sokcetClient.on('join', (roomId) => {
        //加入房間
        sokcetClient.join(roomId);
        //通知某設(shè)備加入房間
        sokcetClient.in(roomId).emit('joined', roomId, sokcetClient.id);
    });
    sokcetClient.on('leave', (roomId) => {
        //離開(kāi)房間
        sokcetClient.leave(roomId);
        //通知某設(shè)備離開(kāi)房間
        sokcetClient.in(roomId).emit('leaved', roomId, sokcetClient.id);
    });
    sokcetClient.on('sendRoomMsg',(roomId,msg)=>{
        //向房間內(nèi)推送消息
        sokcetClient.in(roomId).emit('receiveRoomMsg', msg);
    })
});

其中socket.io中部分常用的函數(shù)及左右如下:
on:用于監(jiān)聽(tīng)對(duì)應(yīng)的事件夷家,接收的參數(shù)取決于emit發(fā)送的數(shù)據(jù)
emit:用于發(fā)送相應(yīng)的事件
in(roomId).emit:用于在相應(yīng)的房間內(nèi)發(fā)送事件
join(roomId):加入相應(yīng)的房間
leave(roomId):離開(kāi)相應(yīng)的房間

2.客戶端實(shí)現(xiàn)
1.引入依賴

https://socketio.github.io/socket.io-client-java/installation.html


這里由于服務(wù)器不是使用的最新的socketio熟尉,因此我們客戶端也引入1.0.0版本的庫(kù)

implementation ('io.socket:socket.io-client:1.0.0') {
        // excluding org.json which is provided by Android
        exclude group: 'org.json', module: 'json'
    }
2.代碼實(shí)現(xiàn)
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">

    <data>

    </data>

    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/white"
        android:padding="10dp"
        tools:context=".MainActivity">
        <Button
            android:id="@+id/bt_connect"
            android:text="連接"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>
        <Button
            android:id="@+id/bt_joinroom"
            android:text="加入房間"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>
        <Button
            android:id="@+id/bt_disConnect"
            android:text="斷開(kāi)連接"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>
        <EditText
            android:id="@+id/et_sendmsg"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>
        <Button
            android:id="@+id/bt_sendmsg"
            android:text="發(fā)送消息"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>
        <TextView
            android:id="@+id/tv_chat"
            android:layout_marginTop="10dp"
            android:padding="10dp"
            android:background="@drawable/shape_chat"
            android:textColor="@color/black"
            android:textSize="15sp"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>
    </LinearLayout>
</layout>
class MainActivity : AppCompatActivity() {
    private lateinit var mainBinding: ActivityMainBinding
    private var socket: Socket? = null
    private var roomId = "111" //房間號(hào)
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        mainBinding = DataBindingUtil.setContentView<ActivityMainBinding>(this,R.layout.activity_main)
        mainBinding.lifecycleOwner = this
        initListener()
    }

    private fun initListener() {
        mainBinding.btConnect.setOnClickListener {
            connectSocketIo()
        }
        mainBinding.btDisConnect.setOnClickListener {
            socket?.let {
                //發(fā)送離開(kāi)事件
                it.emit("leave",roomId)
                it.disconnect()
                it.close()
            }
        }
        mainBinding.btJoinroom.setOnClickListener {
            socket?.let {
                //發(fā)送加入事件
                it.emit("join",roomId)
            }
        }
        mainBinding.btSendmsg.setOnClickListener {
            var msg = mainBinding.etSendmsg.text.toString()
            //發(fā)送消息就是發(fā)送sendRoomMsg事件,然后服務(wù)器會(huì)進(jìn)行轉(zhuǎn)發(fā)
            socket?.let {
                it.emit("sendRoomMsg",roomId,msg)
                addMsg2View(msg)
            }
        }
    }

    private fun connectSocketIo(){
        socket = IO.socket("http://192.168.16.52:3000/").apply {
            connect()
            //接收joined事件莹菱,用于提醒有人加入房間了
            on("joined") {
                var roomId = it[0]
                var clientId = it[1]
                Log.e("加入","房間id:$roomId 客戶端id:$clientId")
                runOnUiThread {
                    Toast.makeText(this@MainActivity,"客戶端:$clientId 加入房間",Toast.LENGTH_SHORT).show()
                }
            }
            //接收receiveRoomMsg事件用于對(duì)房間消息的顯示
            on("receiveRoomMsg") {
                var roomMsg = it[0]
                runOnUiThread {
                    addMsg2View(roomMsg as String)
                }
            }
        }

    }

    /**
     * 添加消息到控件
     */
    private fun addMsg2View(roomMsg: String) {
        var currentMsg = mainBinding.tvChat.text.toString()
        if(TextUtils.isEmpty(currentMsg)){
            mainBinding.tvChat.text = "$roomMsg"
        }else{
            mainBinding.tvChat.text = "$currentMsg \n $roomMsg"
        }
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末鞭呕,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子篇恒,更是在濱河造成了極大的恐慌扶檐,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,204評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件胁艰,死亡現(xiàn)場(chǎng)離奇詭異款筑,居然都是意外死亡智蝠,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門奈梳,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)杈湾,“玉大人,你說(shuō)我怎么就攤上這事攘须∑嶙玻” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 164,548評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵阻课,是天一觀的道長(zhǎng)叫挟。 經(jīng)常有香客問(wèn)我,道長(zhǎng)限煞,這世上最難降的妖魔是什么抹恳? 我笑而不...
    開(kāi)封第一講書人閱讀 58,657評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮署驻,結(jié)果婚禮上奋献,老公的妹妹穿的比我還像新娘。我一直安慰自己旺上,他們只是感情好瓶蚂,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,689評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著宣吱,像睡著了一般窃这。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上征候,一...
    開(kāi)封第一講書人閱讀 51,554評(píng)論 1 305
  • 那天杭攻,我揣著相機(jī)與錄音,去河邊找鬼疤坝。 笑死兆解,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的跑揉。 我是一名探鬼主播锅睛,決...
    沈念sama閱讀 40,302評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼历谍!你這毒婦竟也來(lái)了现拒?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 39,216評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤望侈,失蹤者是張志新(化名)和其女友劉穎印蔬,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體甜无,經(jīng)...
    沈念sama閱讀 45,661評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡扛点,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,851評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了岂丘。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片陵究。...
    茶點(diǎn)故事閱讀 39,977評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖奥帘,靈堂內(nèi)的尸體忽然破棺而出铜邮,到底是詐尸還是另有隱情,我是刑警寧澤寨蹋,帶...
    沈念sama閱讀 35,697評(píng)論 5 347
  • 正文 年R本政府宣布松蒜,位于F島的核電站,受9級(jí)特大地震影響已旧,放射性物質(zhì)發(fā)生泄漏秸苗。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,306評(píng)論 3 330
  • 文/蒙蒙 一运褪、第九天 我趴在偏房一處隱蔽的房頂上張望惊楼。 院中可真熱鬧,春花似錦秸讹、人聲如沸檀咙。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,898評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)弧可。三九已至,卻和暖如春劣欢,著一層夾襖步出監(jiān)牢的瞬間棕诵,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,019評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工氧秘, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留年鸳,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,138評(píng)論 3 370
  • 正文 我出身青樓丸相,卻偏偏與公主長(zhǎng)得像搔确,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子灭忠,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,927評(píng)論 2 355