GVKun编程网logo

在 socket.io 的聊天室中获取多少人(基于socket的聊天程序)

13

如果您对在socket.io的聊天室中获取多少人感兴趣,那么本文将是一篇不错的选择,我们将为您详在本文中,您将会了解到关于在socket.io的聊天室中获取多少人的详细内容,我们还将为您解答基于soc

如果您对在 socket.io 的聊天室中获取多少人感兴趣,那么本文将是一篇不错的选择,我们将为您详在本文中,您将会了解到关于在 socket.io 的聊天室中获取多少人的详细内容,我们还将为您解答基于socket的聊天程序的相关问题,并且为您提供关于9、socket.io,websocket 前后端实时通信,(聊天室的实现)、c#基于WinForm的Socket实现简单的聊天室 IM、Flex和java的socket通信(四)一个简单的聊天室、Java Socket 聊天室编程 (一) 之利用 socket 实现聊天之消息推送的有价值信息。

本文目录一览:

在 socket.io 的聊天室中获取多少人(基于socket的聊天程序)

在 socket.io 的聊天室中获取多少人(基于socket的聊天程序)

我现在有这段代码设置了缺口和余地:

io.sockets.on(''connection'', function(client){    var Room = "";    client.on("setNickAndRoom", function(nick, fn){        client.join(nick.room);        Room = nick.room;        client.broadcast.to(Room).emit(''count'', "Connected:" + " " + count);        fn({msg :"Connected:" + " " + count});    });

我想知道我如何才能有多少人连接到特定的聊天室…例如Room.length

客户端 :

function Chat(){    this.socket = null;    this.Nickname = "";    this.Room = "";    var synched = $(''#syncUp'');    this.Connect = function(nick, room){         socket =  io.connect(''http://vybeing.com:8080'');            Nickname = nick;        Room = room;        //conectarse        socket.on(''connect'',function (data) {            socket.emit(''setNickAndRoom'', {nick: nick, room: room}, function(response){                $("#connection").html("<p>" + response.msg + "</p>");            });        });}

我发现了这一点,但给出了未定义的内容:

count = io.rooms[Room].length;

答案1

小编典典

对于socket.io版本> = 1.0:

请注意,房间成为具有.length1.4属性的实际类型,因此1.4.x方法从现在开始应该是稳定的。当然,禁止对该类型的API进行重大更改。

计算所有连接到的客户端’my_room’:

1.4+:

var room = io.sockets.adapter.rooms[''my_room''];room.length;

1.3.x:

var room = io.sockets.adapter.rooms[''my_room''];Object.keys(room).length;

1.0.x至1.2.x:

var room = io.adapter.rooms[''my_room''];Object.keys(room).length;

这是假设您在单个节点(而不是集群)上使用默认的Room适配器运行。如果您在集群中,事情会更加复杂。

其他相关示例:

计算连接到服务器的所有客户端:

var srvSockets = io.sockets.sockets;Object.keys(srvSockets).length;

计算连接到名称空间的所有客户端’/chat’:

var nspSockets = io.of(''/chat'').sockets;Object.keys(nspSockets).length

9、socket.io,websocket 前后端实时通信,(聊天室的实现)

9、socket.io,websocket 前后端实时通信,(聊天室的实现)

websocket 一种通信协议

ajax/jsonp 单工通信

websocket 全双工通信 性能高 速度快


2种方式:

1、前端的websocket
2、后端的 socket.io

demo地址:github

一、后端socket.io

https://socket.io/
安装:

cnpm i socket.io

接收on  发送emit ——可以发送任意类型的数据

后端:

1、创建httpServer
2、创建wsServer var ws = io(httpServer);
3、连接

ws.on("connect",function(socket){
   		
   		//45  发送或者接收  
   		发送  socket.emit("名称",数据); 
   		广播  socket.broadcast.emit("名称",数据); 
   		接收  socket.on(名称,function(data——数据){
   			
   		      });
   
   });

前端:
1、引入js src="/socket.io/socket.io.js"
2、连接
var ws = io("ws://ip:port");
3、发送接收 on/emit

聊天室:

chat.html

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>无标题文档</title>
<style>
*{padding:0;margin:0;list-style:none;}
#div1{ position:relative;width:500px; height:400px; border:1px solid red;}
#text{ position:absolute;left:0;bottom:0;width:80%; height:100px;}
#btn1{ position:absolute;right:0;bottom:0;width:20%; height:100px;}
#ul1{width:100%; height:300px; background:#ccc; overflow-y:auto;}
#ul1 li{ line-height:30px; border-bottom:1px dashed red;}
</style>
<!--<script src="/socket.io/socket.io.js"></script>-->
<script src="https://cdn.bootcss.com/socket.io/2.1.1/socket.io.js"></script>
<script>//http://10.30.155.92
//var ws = io("ws://10.30.155.92:9000");
//var ws = io("http://10.30.155.92:9000");
//var ws = io();
var ws = io.connect("ws://10.30.155.92:9000");//标准写法 ws://
window.onload = function(){
	var oUl = document.getElementById("ul1");
	var oText = document.getElementById("text");
	var oBtn = document.getElementById("btn1");	
	
	
	var name = prompt("请输入你的用户名")//"张三";
	oBtn.onclick = function(){
		//发送数据
		var data = {name:name,value:oText.value};
		ws.emit("msg",data);
		
		createLi(data);
	};
	
	//接收数据 1创建dom
	ws.on("msg_all",function(data){
		console.log(data);
		createLi(data);
	});
	
	function createLi(data){
		//创建dom
		var oLi = document.createElement("li");
		oLi.innerHTML = `<strong>${data.name}</strong> <span>${data.value}</span>`	;
		oUl.appendChild(oLi);	
		oUl.scrollTop = oUl.scrollHeight;
			
	}
};
</script>
</head>

<body>
<div id="div1">
	<ul id="ul1">
    	<!--<li><strong>张三</strong> <span>聊天内容</span></li>-->
    </ul>
    <textarea id="text"></textarea>
    <input id="btn1" type="button" value="发送"/>
</div>
</body>
</html>

chat.js

var http = require("http");
var io = require("socket.io");
var fs = require("fs");

//创建http服务
var httpServer = http.createServer(function(req,res){
	var url = req.url;
	fs.readFile("www"+url,function(err,data){
		if(err){
			res.end("404");
		} else {
			res.end(data);	
		}
	});
		
});

httpServer.listen(9000);

//创建websockt服务

var ws = io(httpServer);

ws.on("connection",function(socket){
	console.log("wsServer");
	
	//接收数据
	socket.on("msg",function(data){
		console.log(data);	
		
		//发送数据广播
		socket.broadcast.emit("msg_all",data);
	});	
});

前端H5 WebSocket

ws: http
wss:https

前端配置:
var ws = new WebSocket("ws://ip:port");

ws.onopen = function(evt) { 
  console.log("Connection open ..."); 
  ws.send("Hello WebSockets!");
};

ws.onmessage = function(evt) {
  console.log( "Received Message: " + evt.data);
  ws.close();
};

ws.onclose = function(evt) {
  console.log("Connection closed.");
};

后端:npm i ws

npm i ws

https://www.npmjs.com/package/ws

var wss = new WebSocket({server:httpServer});

wss.on("connection",function(ws,req){

		发送 接收
		
		接收
		ws.onmessage(function(ev){
			//数据 ev.data
			
	  });
	  
	  发送:
	  ws.send(数据);
	  
	  数据 最好只能是字符串!!!
	
});

==exp:==

h5.html
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>无标题文档</title>
<script>

var ws = new WebSocket("ws://localhost:9000");

//建立连接
ws.onopen = function(ev) { 
  console.log("连接成功"); 
};

//接收数据
ws.onmessage = function(ev) {
  console.log( "接收数据",ev.data);//server--->client
  //发送数据
  //ws.send("client--->server");
  try{
	  //只处理json
	  var json = JSON.parse(ev.data);
	  console.log(json);
	  if(json.type == "click"){
		  var oSpan = document.getElementById("s1");
		  oSpan.innerHTML = json.value;
	  }
  }catch(e){
	  
  }
};

//连接关闭
ws.onclose = function(evt) {
  console.log("连接关闭");
};     

 
window.onload = function(){
	var oBtn = document.getElementById("btn1");
	
	oBtn.onclick = function(){
		//发送数据 只能发送字符串 
		ws.send(JSON.stringify({type:"click",value:"abc"}));
	};
	
}


</script>
</head>

<body>

h5 WebSocket
<input id="btn1" type="button" value="发送"/><span id="s1">1111</span>
</body>
</html>

h5.js:
var http = require("http");
var WebSocket = require("ws");
var fs = require("fs");

//创建http服务
var httpServer = http.createServer(function(req,res){
	var url = req.url;
	fs.readFile("www"+url,function(err,data){
		if(err){
			res.end("404");
		} else {
			res.end(data);	
		}
	});
		
});

httpServer.listen(9000);

//创建websockt服务

var wss = new WebSocket.Server({ server:httpServer });
 
wss.on(''connection'', function connection(ws) {
	  console.log("wsServer");
	  //发送 send
	  ws.send("server--->client");
	  
	  //接收
	  ws.on(''message'', function(message) {
		  
		  console.log(message);
		  
		  //ws.send(message);
		  //广播
		  wss.clients.forEach(function(client) {
			if (client.readyState === WebSocket.OPEN) {
			  client.send(message);
			}
		  });
					  
		  
	  }); 
});










爱我所爱无怨无悔

c#基于WinForm的Socket实现简单的聊天室 IM

c#基于WinForm的Socket实现简单的聊天室 IM

1:什么是Socket

所谓套接字(Socket),就是对网络中不同主机上的应用进程之间进行双向通信的端点的抽象。

一个套接字就是网络上进程通信的一端,提供了应用层进程利用网络协议交换数据的机制。

从所处的地位来讲,套接字上联应用进程,下联网络协议栈,是应用程序通过网络协议进行通信的接口,是应用程序与网络协议根进行交互的接口。

2:客服端和服务端的通信简单流程

3:服务端Code:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace ChartService
{
    using System.Net;
    using System.Net.Sockets;
    using System.Threading;
    using ChatCommoms;
    using ChatModels;

    public partial class ServiceForm : Form
    {
        Socket _socket;
        private static List<ChatUserInfo> userinfo = new List<ChatUserInfo>();
        public ServiceForm()
        {
            InitializeComponent();

        }

        private void btnServicStart_Click(object sender, EventArgs e)
        {
            try
            {
                string ip = textBox_ip.Text.Trim();
                string port = textBox_port.Text.Trim();
                if (string.IsNullOrWhiteSpace(ip) || string.IsNullOrWhiteSpace(port))
                {
                    MessageBox.Show("IP与端口不可以为空!");
                }
                ServiceStartAccept(ip, int.Parse(port));
            }
            catch (Exception)
            {
                MessageBox.Show("连接失败!或者ip,端口参数异常");
            }
        }
        public void ServiceStartAccept(string ip, int port)
        {
            Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            IPEndPoint endport = new IPEndPoint(IPAddress.Parse(ip), port);
            socket.Bind(endport);
            socket.Listen(10);
            Thread thread = new Thread(Recevice);
            thread.IsBackground = true;
            thread.Start(socket);
            textboMsg.AppendText("服务开启ok...");
        }

        /// <summary>
        /// 开启接听服务
        /// </summary>
        /// <param name="obj"></param>
        private void Recevice(object obj)
        {
            var socket = obj as Socket;
            while (true)
            {
                string remoteEpInfo = string.Empty;
                try
                {
                    Socket txSocket = socket.Accept();
                    _socket = txSocket;
                    if (txSocket.Connected)
                    {
                        remoteEpInfo = txSocket.RemoteEndPoint.ToString();
                        textboMsg.AppendText($"\r\n{remoteEpInfo}:连接上线了...");
                        var clientUser = new ChatUserInfo
                        {
                            UserID = Guid.NewGuid().ToString(),
                            ChatUid = remoteEpInfo,
                            ChatSocket = txSocket
                        };
                        userinfo.Add(clientUser);


                        listBoxCoustomerList.Items.Add(new ChatUserInfoBase { UserID = clientUser.UserID, ChatUid = clientUser.ChatUid });
                        listBoxCoustomerList.DisplayMember = "ChatUid";
                        listBoxCoustomerList.ValueMember = "UserID";

                        ReceseMsgGoing(txSocket, remoteEpInfo);
                    }
                    else
                    {
                        if (userinfo.Count > 0)
                        {
                            userinfo.Remove(userinfo.Where(c => c.ChatUid == remoteEpInfo).FirstOrDefault());
                            //移除下拉框对于的socket或者叫用户
                        }
                        break;
                    }
                }
                catch (Exception)
                {
                    if (userinfo.Count > 0)
                    {
                        userinfo.Remove(userinfo.Where(c => c.ChatUid == remoteEpInfo).FirstOrDefault());
                        //移除下拉框对于的socket或者叫用户
                    }
                }
            }

        }

        /// <summary>
        /// 接受来自客服端发来的消息
        /// </summary>
        /// <param name="txSocket"></param>
        /// <param name="remoteEpInfo"></param>
        private void ReceseMsgGoing(Socket txSocket, string remoteEpInfo)
        {

            //退到一个客服端的时候 int getlength = txSocket.Receive(recesiveByte); 有抛异常
            Thread thread = new Thread(() =>
            {
                while (true)
                {
                    try
                    {
                        byte[] recesiveByte = new byte[1024 * 1024 * 4];
                        int getlength = txSocket.Receive(recesiveByte);
                        if (getlength <= 0) { break; }

                        var getType = recesiveByte[0].ToString();
                        string getmsg = Encoding.UTF8.GetString(recesiveByte, 1, getlength - 1);
                        ShowMsg(remoteEpInfo, getType, getmsg);
                    }
                    catch (Exception)
                    {
                        //string userid = userinfo.FirstOrDefault(c => c.ChatUid == remoteEpInfo)?.ChatUid;
                        listBoxCoustomerList.Items.Remove(remoteEpInfo);
                        userinfo.Remove(userinfo.FirstOrDefault(c => c.ChatUid == remoteEpInfo));//从集合中移除断开的socket

                        listBoxCoustomerList.DataSource = userinfo;//重新绑定下来的信息
                        listBoxCoustomerList.DisplayMember = "ChatUid";
                        listBoxCoustomerList.ValueMember = "UserID";
                        txSocket.Dispose();
                        txSocket.Close();
                    }
                }
            });
            thread.IsBackground = true;
            thread.Start();

        }

        private void ShowMsg(string remoteEpInfo, string getType, string getmsg)
        {
            textboMsg.AppendText($"\r\n{remoteEpInfo}:消息类型:{getType}:{getmsg}");
        }
        private void Form1_Load(object sender, EventArgs e)
        {
            CheckForIllegalCrossThreadCalls = false;
            this.textBox_ip.Text = "192.168.1.101";//初始值
            this.textBox_port.Text = "50000";
        }

        /// <summary>
        /// 服务器发送消息,可以先选择要发送的一个用户
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnSendMsg_Click(object sender, EventArgs e)
        {
            var getmSg = textBoxSendMsg.Text.Trim();
            if (string.IsNullOrWhiteSpace(getmSg))
            {
                MessageBox.Show("要发送的消息不可以为空", "注意"); return;
            }
            var obj = listBoxCoustomerList.SelectedItem;
            int getindex = listBoxCoustomerList.SelectedIndex;
            if (obj == null || getindex == -1)
            {
                MessageBox.Show("请先选择左侧用户的用户"); return;
            }
            var getChoseUser = obj as ChatUserInfoBase;
            var sendMsg = ServiceSockertHelper.GetSendMsgByte(getmSg, ChatTypeInfoEnum.StringEnum);
            userinfo.FirstOrDefault(c => c.ChatUid == getChoseUser.ChatUid)?.ChatSocket?.Send(sendMsg);
        }

        /// <summary>
        /// 给所有登录的用户发送消息,群发了
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button1_Click(object sender, EventArgs e)
        {
            var getmSg = textBoxSendMsg.Text.Trim();
            if (string.IsNullOrWhiteSpace(getmSg))
            {
                MessageBox.Show("要发送的消息不可以为空", "注意"); return;
            }
            if (userinfo.Count <= 0)
            {
                MessageBox.Show("暂时没有客服端登录!"); return;
            }
            var sendMsg = ServiceSockertHelper.GetSendMsgByte(getmSg, ChatTypeInfoEnum.StringEnum);
            foreach (var usersocket in userinfo)
            {
                usersocket.ChatSocket?.Send(sendMsg);
            }
        }

        /// <summary>
        /// 服务器给发送震动
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnSendSnak_Click(object sender, EventArgs e)
        {
            var obj = listBoxCoustomerList.SelectedItem;
            int getindex = listBoxCoustomerList.SelectedIndex;
            if (obj == null || getindex == -1)
            {
                MessageBox.Show("请先选择左侧用户的用户"); return;
            }
            var getChoseUser = obj as ChatUserInfoBase;

            byte[] sendMsgByte = ServiceSockertHelper.GetSendMsgByte("", ChatTypeInfoEnum.Snake);
            userinfo.FirstOrDefault(c => c.ChatUid == getChoseUser.ChatUid)?.ChatSocket.Send(sendMsgByte);
        }


    }
}

4:客服端Code:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace ChatClient
{
    using ChatCommoms;
    using System.Net;
    using System.Net.Sockets;
    using System.Threading;

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            CheckForIllegalCrossThreadCalls = false;
            this.textBoxIp.Text = "192.168.1.101";//先初始化一个默认的ip等
            this.textBoxPort.Text = "50000";
        }

        Socket clientSocket;
        /// <summary>
        /// 客服端连接到服务器
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnServicStart_Click(object sender, EventArgs e)
        {
            try
            {
                var ipstr = textBoxIp.Text.Trim();
                var portstr = textBoxPort.Text.Trim();
                if (string.IsNullOrWhiteSpace(ipstr) || string.IsNullOrWhiteSpace(portstr))
                {
                    MessageBox.Show("要连接的服务器ip和端口都不可以为空!");
                    return;
                }
                clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                clientSocket.Connect(IPAddress.Parse(ipstr), int.Parse(portstr));
                labelStatus.Text = "连接到服务器成功...!";
                ReseviceMsg(clientSocket);

            }
            catch (Exception)
            {
                MessageBox.Show("请检查要连接的服务器的参数");
            }
        }
        private void ReseviceMsg(Socket clientSocket)
        {

            Thread thread = new Thread(() =>
             {
                 while (true)
                 {
                     try
                     {
                         Byte[] byteContainer = new Byte[1024 * 1024 * 4];
                         int getlength = clientSocket.Receive(byteContainer);
                         if (getlength <= 0)
                         {
                             break;
                         }
                         var getType = byteContainer[0].ToString();
                         string getmsg = Encoding.UTF8.GetString(byteContainer, 1, getlength - 1);

                         GetMsgFomServer(getType, getmsg);
                     }
                     catch (Exception ex)
                     {
                     }
                 }
             });
            thread.IsBackground = true;
            thread.Start();

        }

        private void GetMsgFomServer(string strType, string msg)
        {
            this.textboMsg.AppendText($"\r\n类型:{strType};{msg}");
        }

        /// <summary>
        /// 文字消息的发送
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnSendMsg_Click(object sender, EventArgs e)
        {
            var msg = textBoxSendMsg.Text.Trim();
            var sendMsg = ServiceSockertHelper.GetSendMsgByte(msg, ChatModels.ChatTypeInfoEnum.StringEnum);
            int sendMsgLength = clientSocket.Send(sendMsg);
        }
    }
}

5:测试效果:

6:完整Code GitHUb下载路径 

https://github.com/zrf518/WinformSocketChat.git

7:这个只是一个简单的聊天练习Demo,待进一步完善(实现部分功能,传递的消息byte[0]为消息的类型,用来判断是文字,还是图片等等),欢迎大家指教

以上就是c#基于WinForm的Socket实现简单的聊天室 IM的详细内容,更多关于c# WinForm实现聊天室 IM的资料请关注其它相关文章!

您可能感兴趣的文章:
  • C#基于Socket实现简单聊天室功能
  • ASP.net(C#)实现简易聊天室功能
  • C#简单聊天室雏形
  • C#使用WebSocket实现聊天室功能
  • C#实现简易多人聊天室
  • C#使用Socket实现本地多人聊天室
  • C#制作简单的多人在线即时交流聊天室
  • 分享一个C#编写简单的聊天程序(详细介绍)
  • C#聊天程序服务端与客户端完整实例代码
  • C#基于Socket的TCP通信实现聊天室案例

Flex和java的socket通信(四)一个简单的聊天室

Flex和java的socket通信(四)一个简单的聊天室

知识点:消息广播者类名为Bmanager,他继承了Vector类

class Bmanager extends Vector
{
    Bmanager(){}
void add(Socket socket)
{
    //添加套接字
}
void remove(Socket socket)
{
    //删除套接字
}
synchronized void sendToAll(String msg)
{‘
    //使用套接字的输出流,输出消息
}
synchronized void sendClientInfo()
{
    //使用套接字的输出流,输出当前聊天人数
}
}

  客户端代码:Client5.mxml

<?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" fontSize="12" creationComplete="initApp()" width="369" height="326"> <mx:Script>     <![CDATA[           import flash.net.socket; //导入类包           import flash.utils.ByteArray;//ByteArray在读取数据时使用           private var socket:Socket=new Socket();//定义socket           internal function initApp():void           {                socket.connect("127.0.0.1",8888);//执行连接                //监听连接成功事件                socket.addEventListener(Event.CONNECT,funConnect);                //监听关闭事件                socket.addEventListener(Event.CLOSE,funClose);                //监听服务器新信息                socket.addEventListener(ProgressEvent.soCKET_DATA,funSocket);           }           internal function funConnect(event:Event):void           {                myText.text+="连接已建立 n";           }           internal function funClose(event:Event):void           {                myText.text+="连接已关闭 n";           }           internal function sendMessage(msg:String):void //发送数据到服务器           {                //新建一个ByteArray来存放数据                var message:ByteArray=new ByteArray();                //写入数据,使用writeUTFBytes以utf8格式传数据,避免中文乱码                message.writeUTFBytes(msg+"n");                //写入socket的缓冲区                socket.writeBytes(message); //调用flush方法发送信息                socket.flush();                //清空消息框                myInput.text="";           }           //接受服务器信息           internal function funSocket(event:ProgressEvent):void           {                var msg:String="";           //循环读取数据,socket的bytesAvailable对象存放了服务器传来的所有数据                while(socket.bytesAvailable)                {                     //强制使用utf8格式,避免中文乱码                     msg+=socket.readMultiByte(socket.bytesAvailable,"utf8");                     //使用n换行符号把信息切开                     var arr:Array=msg.split('n');                     for(var i:int=0;i<arr.length;i++)                     {                           if(arr[i].length>1)                           {                                //正则表达式,回车符                                var myPattern:RegExp=/r/;                                //删除回车符                                arr[i]=arr[i].replace(myPattern,'');                                //在聊天框中输出                                myText.text+=arr[i]+"n";                           }                     }                     myText.verticalScrollPosition = myText.maxVerticalScrollPosition;//滚动到最下面                }                                }     ]]> </mx:Script>     <mx:TextArea x="10" y="42" width="344" height="247" id="myText"/>     <mx:TextInput x="10" y="297" width="270" id="myInput"/>     <mx:Button x="288" y="298" label="发送" id="myBtn" click="sendMessage(myName.text+':'+myInput.text)"/>     <mx:TextInput x="10" y="10" width="344" text="名字" id="myName"/>      </mx:Application>

Java Socket 聊天室编程 (一) 之利用 socket 实现聊天之消息推送

Java Socket 聊天室编程 (一) 之利用 socket 实现聊天之消息推送

OSC 请你来轰趴啦!1028 苏州源创会,一起寻宝 AI 时代

这篇文章主要介绍了 Java Socket 聊天室编程 (一) 之利用 socket 实现聊天之消息推送的相关资料,非常不错,具有参考借鉴价值,需要的朋友可以参考下

网上已经有很多利用 socket 实现聊天的例子了,但是我看过很多,多多少有一些问题存在。

这里我将实现一个比较完整的聊天例子,并解释其中的逻辑。

由于 socket 这一块比较大,所以我将分出几篇来写一个比较完整的 socket 例子。

这里我们先来实现一个最简单的,服务器与客户端通讯,实现消息推送的功能。

目的:服务器与客户端建立连接,客户端可以向服务器发送消息,服务器可以向客户端推送消息。

1,使用 java 建立 socket 聊天服务器

1,SocketUrls 确定 ip 地址和端口号

public class SocketUrls{
// ip地址
public final static String IP = "192.168.1.110";
// 端口号
public final static int PORT = 8888;
}

2,Main 程序的入口

public class Main {
public static void main(String[] args) throws Exception {
new ChatServer().initServer();
}
}

3,Bean 实体类

用户信息 UserInfoBean

public class Main {
 
public static void main(String[] args) throws Exception {
new ChatServer().initServer();
}
}

聊天信息 MessageBean

public class MessageBean extends UserInfoBean {
private long messageId;// 消息id
private long groupId;// 群id
private boolean isGoup;// 是否是群消息
private int chatType;// 消息类型;1,文本;2,图片;3,小视频;4,文件;5,地理位置;6,语音;7,视频通话
private String content;// 文本消息内容
private String errorMsg;// 错误信息
private int errorCode;// 错误代码
//省略get/set方法
}

4,ChatServer 聊天服务,最主要的程序

public class ChatServer {
// socket服务
private static ServerSocket server;
public Gson gson = new Gson();
/**
* 初始化socket服务
*/
public void initServer() {
try {
// 创建一个ServerSocket在端口8080监听客户请求
server = new ServerSocket(SocketUrls.PORT);
createMessage();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 创建消息管理,一直接收消息
*/
private void createMessage() {
try {
System.out.println("等待用户接入 : ");
// 使用accept()阻塞等待客户请求
Socket socket = server.accept();
System.out.println("用户接入 : " + socket.getPort());
// 开启一个子线程来等待另外的socket加入
new Thread(new Runnable() {
public void run() {
createMessage();
}
}).start();
// 向客户端发送信息
OutputStream output = socket.getOutputStream();
// 从客户端获取信息
BufferedReader bff = new BufferedReader(new InputStreamReader(socket.getInputStream()));
// Scanner scanner = new Scanner(socket.getInputStream());
new Thread(new Runnable() {
public void run() {
try {
String buffer;
while (true) {
// 从控制台输入
BufferedReader strin = new BufferedReader(new InputStreamReader(System.in));
buffer = strin.readLine();
// 因为readLine以换行符为结束点所以,结尾加入换行
buffer += "
";
output.write(buffer.getBytes("utf-8"));
// 发送数据
output.flush();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
// 读取发来服务器信息
String line = null;
// 循环一直接收当前socket发来的消息
while (true) {
Thread.sleep(500);
// System.out.println("内容 : " + bff.readLine());
// 获取客户端的信息
while ((line = bff.readLine()) != null) {
MessageBean messageBean = gson.fromJson(line, MessageBean.class);
System.out.println("用户 : " + messageBean.getUserName());
System.out.println("内容 : " + messageBean.getContent());
}
}
// server.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("错误 : " + e.getMessage());
}
}
}

2,Android 端作为移动端连接服务器

1,appliaction 实例化一个全局的聊天服务

public class ChatAppliaction extends Application {
public static ChatServer chatServer;
public static UserInfoBean userInfoBean;
@Override
public void onCreate() {
super.onCreate();
}
}

2,ip 地址和端口号和服务器保持一致

3,聊天实力类同服务器端一样

4,xml 布局。登陆,聊天

1,登录

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<EditText
android:id="@+id/chat_name_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="用户名"
android:text="admin"/>
<EditText
android:id="@+id/chat_pwd_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="密码"
android:text="123123123a"
android:inputType="numberPassword" />
<Button
android:id="@+id/chat_login_btn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="登录" />
</LinearLayout>

2,聊天

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".activity.MainActivity">
<ScrollView
android:id="@+id/scrollView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.9">
<LinearLayout
android:id="@+id/chat_ly"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
</LinearLayout>
</ScrollView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<EditText
android:id="@+id/chat_et"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="0.8" />
<Button
android:id="@+id/send_btn"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="0.2"
android:text="发送" />
</LinearLayout>
</LinearLayout>

5,LoginActivity 登陆

public class LoginActivity extends AppCompatActivity {
private EditText chat_name_text, chat_pwd_text;
private Button chat_login_btn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
chat_name_text = (EditText) findViewById(R.id.chat_name_text);
chat_pwd_text = (EditText) findViewById(R.id.chat_pwd_text);
chat_login_btn = (Button) findViewById(R.id.chat_login_btn);
chat_login_btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (getLogin(chat_name_text.getText().toString().trim(), chat_pwd_text.getText().toString().trim())) {
getChatServer();
Intent intent = new Intent(LoginActivity.this, MainActivity.class);
startActivity(intent);
finish();
}
}
});
}
private boolean getLogin(String name, String pwd) {
if (TextUtils.isEmpty(name) || TextUtils.isEmpty(pwd)) return false;
if (name.equals("admin") && pwd.equals("123123123a")) return true;
return false;
}
private void getChatServer() {
ChatAppliaction.chatServer = new ChatServer();
}
}

6,MainActivity 聊天

public class MainActivity extends AppCompatActivity {
private LinearLayout chat_ly;
private TextView left_text, right_view;
private EditText chat_et;
private Button send_btn;
private ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
chat_ly = (LinearLayout) findViewById(R.id.chat_ly);
chat_et = (EditText) findViewById(R.id.chat_et);
send_btn = (Button) findViewById(R.id.send_btn);
send_btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ChatAppliaction.chatServer.sendMessage(chat_et.getText().toString().trim());
chat_ly.addView(initRightView(chat_et.getText().toString().trim()));
}
});
//添加消息接收队列
ChatAppliaction.chatServer.setChatHandler(new Handler() {
@Override
public void handleMessage(Message msg) {
if (msg.what == 1) {
//发送回来消息后,更新ui
chat_ly.addView(initLeftView(msg.obj.toString()));
}
}
});
}
/**靠右的消息
* @param messageContent
* @return
*/
private View initRightView(String messageContent) {
right_view = new TextView(this);
right_view.setLayoutParams(layoutParams);
right_view.setGravity(View.FOCUS_RIGHT);
right_view.setText(messageContent);
return right_view;
}
/**靠左的消息
* @param messageContent
* @return
*/
private View initLeftView(String messageContent) {
left_text = new TextView(this);
left_text.setLayoutParams(layoutParams);
left_text.setGravity(View.FOCUS_LEFT);
left_text.setText(messageContent);
return left_text;
}
}

7,ChatServer 聊天逻辑,最主要的

public class ChatServer {
private Socket socket;
private Handler handler;
private MessageBean messageBean;
private Gson gson = new Gson();
// 由Socket对象得到输出流,并构造PrintWriter对象
PrintWriter printWriter;
InputStream input;
OutputStream output;
DataOutputStream dataOutputStream;
public ChatServer() {
initMessage();
initChatServer();
}
/**
* 消息队列,用于传递消息
*
* @param handler
*/
public void setChatHandler(Handler handler) {
this.handler = handler;
}
private void initChatServer() {
//开个线程接收消息
receiveMessage();
}
/**
* 初始化用户信息
*/
private void initMessage() {
messageBean = new MessageBean();
messageBean.setUserId(1);
messageBean.setMessageId(1);
messageBean.setChatType(1);
messageBean.setUserName("admin");
ChatAppliaction.userInfoBean = messageBean;
}
/**
* 发送消息
*
* @param contentMsg
*/
public void sendMessage(String contentMsg) {
try {
if (socket == null) {
Message message = handler.obtainMessage();
message.what = 1;
message.obj = "服务器已经关闭";
handler.sendMessage(message);
return;
}
byte[] str = contentMsg.getBytes("utf-8");//将内容转utf-8
String aaa = new String(str);
messageBean.setContent(aaa);
String messageJson = gson.toJson(messageBean);
/**
* 因为服务器那边的readLine()为阻塞读取
* 如果它读取不到换行符或者输出流结束就会一直阻塞在那里
* 所以在json消息最后加上换行符,用于告诉服务器,消息已经发送完毕了
* */
messageJson += "
";
output.write(messageJson.getBytes("utf-8"));// 换行打印
output.flush(); // 刷新输出流,使Server马上收到该字符串
} catch (Exception e) {
e.printStackTrace();
Log.e("test", "错误:" + e.toString());
}
}
/**
* 接收消息,在子线程中
*/
private void receiveMessage() {
new Thread(new Runnable() {
@Override
public void run() {
try {
// 向本机的8080端口发出客户请求
socket = new Socket(SocketUrls.IP, SocketUrls.PORT);
// 由Socket对象得到输入流,并构造相应的BufferedReader对象
printWriter = new PrintWriter(socket.getOutputStream());
input = socket.getInputStream();
output = socket.getOutputStream();
dataOutputStream = new DataOutputStream(socket.getOutputStream());
// 从客户端获取信息
BufferedReader bff = new BufferedReader(new InputStreamReader(input));
// 读取发来服务器信息
String line;
while (true) {
Thread.sleep(500);
// 获取客户端的信息
while ((line = bff.readLine()) != null) {
Log.i("socket", "内容 : " + line);
Message message = handler.obtainMessage();
message.obj = line;
message.what = 1;
handler.sendMessage(message);
}
if (socket == null)
break;
}
output.close();//关闭Socket输出流
input.close();//关闭Socket输入流
socket.close();//关闭Socket
} catch (Exception e) {
e.printStackTrace();
Log.e("test", "错误:" + e.toString());
}
}
}).start();
}
}

写到这里,已经完成了所有的代码。

这个 demo 可以实现手机端向服务器发送消息,服务器向手机端发送消息。

这个 demo 可以算是推送功能,不过真正的推送没有这么简单。作为一个 socket 的入门了解,可以从中看到 socket 编程的思想。

以上所述是小编给大家介绍的 Java Socket 聊天室编程 (一) 之利用 socket 实现聊天之消息推送,希望对大家有所帮助,如果大家有任何疑问请给我留言。

我们今天的关于在 socket.io 的聊天室中获取多少人基于socket的聊天程序的分享已经告一段落,感谢您的关注,如果您想了解更多关于9、socket.io,websocket 前后端实时通信,(聊天室的实现)、c#基于WinForm的Socket实现简单的聊天室 IM、Flex和java的socket通信(四)一个简单的聊天室、Java Socket 聊天室编程 (一) 之利用 socket 实现聊天之消息推送的相关信息,请在本站查询。

本文标签: