A. ThinkPHP微的H5聊天室即時通訊系統APP源碼分享
ThinkPHP內核聊天室即時通訊系統源碼是一款類似微信的H5聊天系統APP源碼 。
源碼功能:
消息提醒:有新的消息可以提醒(數字提醒、聲音提醒)。
聊天列表:顯示最近所有的聊天列表,點擊列表某一項可以打開聊天窗口;還可以刪除聊天列表項。
聊天窗口:可以發生文字消息、圖片消息、表情;圖片可以預覽。
站內公告:在頂部顯示可以及時顯示後台發布的公告。
添加朋友:可以搜索對方的帳號名稱然後添加到通訊錄;添加前需要好友驗證才能通過。
群聊:顯示群聊信息。
列表:根據字母分組顯示聯系人;點擊聯系人可以查看詳情資料;可以刪除聯系人。
游戲:可添加你的官方網站或者游戲網站其它~自定義嵌入第三方網站
個人信息:顯示頭像、昵稱、帳號;可以修改頭像和昵稱。
修改密碼:可以修改登錄密碼。
朋友圈:可以發動態。
各種源碼每天更新,還有各種破解軟體、破解游戲、福利寫真圖哦~
網址 www.xqwym.com
B. 求網路聊天室源碼,用JSP或Servlet都行
用ajax和jsp寫的,可以實現無刷新頁面顯示聊天記錄js/js.js文件varnbsp;obj;varnbsp;getId=document.getElementById;functionnbsp;objXMLHttp(){nbsp;nbsp;nbsp;nbsp;varnbsp;XmlHttpObjnbsp;=nbsp;false;nbsp;nbsp;nbsp;nbsp;if(window.ActiveXObject)nbsp;nbsp;nbsp;nbsp;{nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;XmlHttpObjnbsp;=nbsp;newnbsp;ActiveXObject(「MSXML2.XMLHTTP.3.0「);nbsp;nbsp;nbsp;nbsp;}nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;elsenbsp;ifnbsp;(window.XMLHttpRequest)nbsp;nbsp;nbsp;nbsp;{nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;XmlHttpObjnbsp;=nbsp;newnbsp;XMLHttpRequest();nbsp;nbsp;nbsp;nbsp;}nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;returnnbsp;XmlHttpObj;}functionnbsp;sendMsg(auto){nbsp;obj=objXMLHttp();nbsp;if(!auto)//nbsp;{nbsp;nbsp;varnbsp;myContentnbsp;=nbsp;getId(「myText「).value;nbsp;nbsp;if(myContentnbsp;!=nbsp;「「)nbsp;nbsp;{nbsp;nbsp;nbsp;if(obj)nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;{nbsp;nbsp;nbsp;nbsp;obj.onreadystatechangenbsp;=nbsp;addChat;nbsp;nbsp;nbsp;nbsp;obj.open(「POST「,「do.jsp「,nbsp;true);nbsp;nbsp;nbsp;nbsp;obj.setRequestHeader(「Content-Type「,「application/x-www-form-urlencoded;「);nbsp;nbsp;nbsp;nbsp;nbsp;obj.send(「myContent=「nbsp;+nbsp;myContent);nbsp;nbsp;nbsp;nbsp;getId(「myText「).value=「「;nbsp;nbsp;nbsp;nbsp;getId(「myText「).focus();nbsp;nbsp;nbsp;nbsp;Scroll();nbsp;nbsp;nbsp;nbsp;nbsp;nbsp;}nbsp;nbsp;}nbsp;nbsp;elsenbsp;nbsp;{nbsp;nbsp;nbsp;alert(「nbsp;(*^__^*)nbsp;你不告訴我們,我們怎麼知道你們保持沉默呢「);nbsp;nbsp;nbsp;getId(「myText「).value=「保持沉默「;nbsp;nbsp;nbsp;getId(「myText「).focus();nbsp;nbsp;}nbsp;}nbsp;else//nbsp;{nbsp;nbsp;if(obj)nbsp;nbsp;{nbsp;nbsp;nbsp;obj.onreadystatechangenbsp;=nbsp;addChat;nbsp;nbsp;nbsp;obj.open(「POST「,「do.jsp「,nbsp;true);nbsp;nbsp;nbsp;obj.setRequestHeader(「Content-Type「,「application/x-www-form-urlencoded;「);nbsp;nbsp;nbsp;nbsp;obj.send(null);nbsp;nbsp;nbsp;Scroll();nbsp;nbsp;}nbsp;}}functionnbsp;addChat()//添加聊天記錄{nbsp;varnbsp;docnbsp;=nbsp;「「;nbsp;if(obj.readyStatenbsp;==nbsp;4nbsp;amp;amp;nbsp;obj.statusnbsp;==nbsp;200)nbsp;{nbsp;nbsp;doc=obj.responseText;nbsp;nbsp;if(docnbsp;!=nbsp;「「)nbsp;nbsp;{nbsp;nbsp;nbsp;getId(「says「).value=doc;nbsp;nbsp;}nbsp;}}functionnbsp;getChatContent(){nbsp;tnbsp;=nbsp;setInterval(『sendMsg(true)『,800);}functionnbsp;quickSend(){nbsp;nbsp;if(getId(「sendType「).value==「ctrlEnter「)nbsp;{nbsp;nbsp;if(window.event.ctrlKeyamp;amp;window.event.keyCode==13)nbsp;nbsp;{nbsp;nbsp;nbsp;sendMsg(false);nbsp;nbsp;}nbsp;}nbsp;elsenbsp;if(getId(「sendType「).value==「enterKey「)nbsp;{nbsp;nbsp;if(window.event.keyCode==13)nbsp;nbsp;{nbsp;nbsp;nbsp;sendMsg(false);nbsp;nbsp;}nbsp;}}functionnbsp;loginConfirm(){nbsp;if(window.event.keyCode==13)nbsp;{nbsp;nbsp;checkUser();nbsp;}}functionnbsp;checkUser(){nbsp;if(getId(「userName「).value==nullnbsp;||nbsp;getId(「userName「).value=
C. 語音聊天系統源碼的實現,離不開這些功能
語音聊天系統源碼的實現,首先離不開的是它的基礎功能——語音通話。
1、創建用戶界面
根據場景的需要,為項目創建語音通話的用戶界面。
2、獲取設備許可權
調用 checkSelfPermission 方法,在開啟 Activity 時檢查並獲取 Android 移動設備的麥克風使用許可權。
3、 初始化 RtcEngine
在調用其他 Agora API 前,需要創建並初始化 RtcEngine 對象。
將獲取到的 App ID 添加到 string.xml 文件中的 agora_app_id 一欄。調用 create 方法,傳入獲取到的 App ID,即可初始化 RtcEngine。
你還根據場景需要,在初始化時注冊想要監聽的回調事件,如遠端用戶下線或靜音回調。注意不要在這些回調中進行 UI 操作。
語音聊天室平台源碼還要覆蓋社交、 娛樂 、直播、電商等多種泛互聯網行業應用場景
語音聊天室平台源碼可按需搭建直播系統,尤其是語音直播,是當下比較流行的直播產品,語音直播與其他直播不同點在於語音直播是通過聲音傳遞,而無需出現在畫面里,並且聽眾也不需要佔用時間,可以邊聽直播邊做其他,更加解放了雙手雙眼。語音聊天室平台源碼的實時音視頻能力保證了用戶在房間內播放音樂的同時,實時語音溝通依舊流暢,同時提供包括耳返、變聲的趣味化能力,保證最佳的K歌 娛樂 體驗。
各類直播源碼都少不了的社交動態
2、社交話題:語音社交系統源碼用戶在發布動態時,可以添加話題提高曝光度,也可以通過話題獲取更多動態內容。
以上這些功能都是語音聊天系統源碼需要實現的功能,在基礎的語音聊天功能之上,還加入了互動和 娛樂 成分,帶給用戶豐富的體驗。
D. 聊天室程序、系統,聊天室App源碼開發搭建需要哪些功能
直播APP的開發搭建流程:
1. 需求溝通:客戶與產品經理溝通視頻直播APP的大致功能,需要那幾個端,項目開發時間和金額等,確定後即可進入下一步。根據需要的功能和開發周期、價格;付款方式等都寫進合同里。
2. 提供資料:客戶提供營業執照、身份證、對公賬戶等信息。APP搭建流程
3. 確定功能:對於直播產品來講,其自身的優點在於用戶能夠在平台上進行互動和討論,也就是用戶參與的過程,而且在用戶的互動中,激發其他用戶自我表達的慾望。為此對於產品設計而言,應該根據手機的用戶習慣,進行設計交互性強、性能好的產品,以及打造參與門檻低的板塊,進而增強用戶的參與感。
4. UI設計:客戶確定需求後UI設計師根據需求內容將視頻直播APP每一個頁面都以圖片的方式進行呈現,並將做好的UI發與客戶確認,客戶提出修改,修改後確定UI。
5.確定好之後就可以開發搭建直播APP了,當然上架之前還需要測試修改等。
E. 速求用java語言寫聊天室的源代碼
【ClientSocketDemo.java 客戶端Java源代碼】
import java.net.*;
import java.io.*;
public class ClientSocketDemo
{
//聲明客戶端Socket對象socket
Socket socket = null;
//聲明客戶器端數據輸入輸出流
DataInputStream in;
DataOutputStream out;
//聲明字元串數組對象response,用於存儲從伺服器接收到的信息
String response[];
//執行過程中,沒有參數時的構造方法,本地伺服器在本地,取默認埠10745
public ClientSocketDemo()
{
try
{
//創建客戶端socket,伺服器地址取本地,埠號為10745
socket = new Socket("localhost",10745);
//創建客戶端數據輸入輸出流,用於對伺服器端發送或接收數據
in = new DataInputStream(socket.getInputStream());
out = new DataOutputStream(socket.getOutputStream());
//獲取客戶端地址及埠號
String ip = String.valueOf(socket.getLocalAddress());
String port = String.valueOf(socket.getLocalPort());
//向伺服器發送數據
out.writeUTF("Hello Server.This connection is from client.");
out.writeUTF(ip);
out.writeUTF(port);
//從伺服器接收數據
response = new String[3];
for (int i = 0; i < response.length; i++)
{
response[i] = in.readUTF();
System.out.println(response[i]);
}
}
catch(UnknownHostException e){e.printStackTrace();}
catch(IOException e){e.printStackTrace();}
}
//執行過程中,有一個參數時的構造方法,參數指定伺服器地址,取默認埠10745
public ClientSocketDemo(String hostname)
{
try
{
//創建客戶端socket,hostname參數指定伺服器地址,埠號為10745
socket = new Socket(hostname,10745);
in = new DataInputStream(socket.getInputStream());
out = new DataOutputStream(socket.getOutputStream());
String ip = String.valueOf(socket.getLocalAddress());
String port = String.valueOf(socket.getLocalPort());
out.writeUTF("Hello Server.This connection is from client.");
out.writeUTF(ip);
out.writeUTF(port);
response = new String[3];
for (int i = 0; i < response.length; i++)
{
response[i] = in.readUTF();
System.out.println(response[i]);
}
}
catch(UnknownHostException e){e.printStackTrace();}
catch(IOException e){e.printStackTrace();}
}
//執行過程中,有兩個個參數時的構造方法,第一個參數hostname指定伺服器地址
//第一個參數serverPort指定伺服器埠號
public ClientSocketDemo(String hostname,String serverPort)
{
try
{
socket = new Socket(hostname,Integer.parseInt(serverPort));
in = new DataInputStream(socket.getInputStream());
out = new DataOutputStream(socket.getOutputStream());
String ip = String.valueOf(socket.getLocalAddress());
String port = String.valueOf(socket.getLocalPort());
out.writeUTF("Hello Server.This connection is from client.");
out.writeUTF(ip);
out.writeUTF(port);
response = new String[3];
for (int i = 0; i < response.length; i++)
{
response[i] = in.readUTF();
System.out.println(response[i]);
}
}
catch(UnknownHostException e){e.printStackTrace();}
catch(IOException e){e.printStackTrace();}
}
public static void main(String[] args)
{
String comd[] = args;
if(comd.length == 0)
{
System.out.println("Use localhost(127.0.0.1) and default port");
ClientSocketDemo demo = new ClientSocketDemo();
}
else if(comd.length == 1)
{
System.out.println("Use default port");
ClientSocketDemo demo = new ClientSocketDemo(args[0]);
}
else if(comd.length == 2)
{
System.out.println("Hostname and port are named by user");
ClientSocketDemo demo = new ClientSocketDemo(args[0],args[1]);
}
else System.out.println("ERROR");
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
【ServerSocketDemo.java 伺服器端Java源代碼】
import java.net.*;
import java.io.*;
public class ServerSocketDemo
{
//聲明ServerSocket類對象
ServerSocket serverSocket;
//聲明並初始化伺服器端監聽埠號常量
public static final int PORT = 10745;
//聲明伺服器端數據輸入輸出流
DataInputStream in;
DataOutputStream out;
//聲明InetAddress類對象ip,用於獲取伺服器地址及埠號等信息
InetAddress ip = null;
//聲明字元串數組對象request,用於存儲從客戶端發送來的信息
String request[];
public ServerSocketDemo()
{
request = new String[3]; //初始化字元串數組
try
{
//獲取本地伺服器地址信息
ip = InetAddress.getLocalHost();
//以PORT為服務埠號,創建serverSocket對象以監聽該埠上的連接
serverSocket = new ServerSocket(PORT);
//創建Socket類的對象socket,用於保存連接到伺服器的客戶端socket對象
Socket socket = serverSocket.accept();
System.out.println("This is server:"+String.valueOf(ip)+PORT);
//創建伺服器端數據輸入輸出流,用於對客戶端接收或發送數據
in = new DataInputStream(socket.getInputStream());
out = new DataOutputStream(socket.getOutputStream());
//接收客戶端發送來的數據信息,並顯示
request[0] = in.readUTF();
request[1] = in.readUTF();
request[2] = in.readUTF();
System.out.println("Received messages form client is:");
System.out.println(request[0]);
System.out.println(request[1]);
System.out.println(request[2]);
//向客戶端發送數據
out.writeUTF("Hello client!");
out.writeUTF("Your ip is:"+request[1]);
out.writeUTF("Your port is:"+request[2]);
}
catch(IOException e){e.printStackTrace();}
}
public static void main(String[] args)
{
ServerSocketDemo demo = new ServerSocketDemo();
}
}
F. 直播源碼,直播系統如何開發搭建與運營
直播的火爆讓各行各業對直播這塊新市場垂涎不已,而進軍直播市場的第一步——直播系統源碼卻讓企業頭疼不已,那麼直播系統源碼如何進行開發呢?一、媒體模塊:1、採集:通過SDK介面,直接從用戶設備採集視頻、音頻等數據,視頻采樣數據一般採用RGB或YUV格式、音頻采樣數據一般採用PCM格式。2、預處理:對採集到的數據通過SDK層面介面進行潤化處理,主要是圖像方面的處理,如美顏、水印、濾鏡等,GPU優化提速,平衡手機功耗及效果。3、編碼:對採集到的數據進行壓縮編碼,比較常用的視頻編碼為H.264,音頻為AAC,在解析度、幀數、碼率等參數設計上找到最佳平衡點,使之匹配推流所需協議,提高上傳效率。4、推拉流:推流就是將壓縮後的音視頻變為流數據,上傳至伺服器。拉流即通過播放端獲取碼流,從服務端拉取支持以RTMP、HTTP-FLV及HLS等協議的音視頻流。5、解碼:對拉流獲取封裝的視頻數據進行高性能解碼,讓直播更流暢。6、播放:解碼後的音頻數據即可在播放端進行播放,支持包括MP4、FLV、M3U8等多樣視頻播放格式。
二、服務模塊
1、聊天系統:包括聊天室功能、彈幕、私聊
2、禮物系統:禮物的收發,禮物的圖形
3、支付系統:充值、提現、收益兌換
4、運行系統:提供直播方案
5、安全系統:實名認證、截圖、自動鑒黃、錄制、回播、禁播6、統計系統:點擊量、收益、流量統計
三、管理模塊
1、前端:移動端、PC端頁面效果展示設計,維護
2、後台:管理運營,資料庫管理
我們都知道,搭建一個完整的直播平台過程包括:採集、處理、編碼、推流、分發、解碼和播放,搭建直播平台是需要藉助三方賬號的支持的,比如伺服器、推拉流、簡訊服務等,搭建直播平台都也是如此,除了本身的系統功能外,想用直播系統源碼搭建平台,還需要一些三方的協助:
1、 CDN,提供視頻加速和視頻分發服務,一般視頻cdn可以使用騰訊的直播cdn加速服務,也可以使用ucloud的視頻cnd加速服務,具體費用咨詢對應廠商客服。只要是支持rtmp直播協議的就可以。
2、 美顏SDK,實現美顏功能
3、 支付賬號,支付寶支付和微信支付的支付賬號
4、 雲存儲,大量的錄播視頻、短視頻、直播間實時互動消息,需要動態存儲和靜態存儲的支持。
5、登錄和分享的賬號,微信和qq的登錄和分享
6、 蘋果公司開發者賬號,分發和蘋果上架使用。
眾多的三方介面接入也是直播系統源碼平台後期能夠正常運營的先決條件,好在大部分直播系統源碼服務商都可以提供協助接入服務免去了很多後顧之憂,因此搭建運營直播系統源碼平台不僅僅要選對直播系統源碼,還要選擇正確的服務商。
G. 一對一直播系統源碼都有哪些功能開發
、多終端同步功能
直播初的誕生是在PC端,但是隨著現代智能手機的普及和移動網路的進步,手機端成為了直播觀看的大平台,直播系統如今也可以實現PC端、Android端與iOS端三端互通,均可開播觀看,這也是直播系統發展客戶的基本功能;
2、多渠道注冊/登錄
登錄
隨著微信、微博的火熱,直播系統的登陸已經不僅僅限於手機驗證碼、QQ注冊登錄,微博微信也成為新的主流的登錄方式,甚至通過Twitter、Facebook也可注冊登錄;
3、多渠道充值/提現
目前支付寶、微信支付基本占據了現在中國移動支付的整個市場,一套優秀的直播系統源碼必定離不開這兩種支付方式的介面,其次,能否接入四方支付介面也是考驗直播系統源碼的一個重要因素;
4、聊天互動及彈幕功能
一對一直播系統之所以如此火爆,正是因為粉絲可以發送彈幕或私信給主播,拉近了主播與粉絲之間的距離。實時彈幕是主播與粉絲交流的主要方式,實際上就是IM聊天中的聊天室功能,不需要查看歷史消息只有在線用戶可以實時看到聊天信息。由於網路狀況復雜且不穩定,還要根據用戶位置選擇較近的對應運營商的單線機房,來保證彈幕的實時性;
5、多渠道分享
多渠道分享類似於多渠道注冊/登陸,通過主流的社交平台將直播間分享出去,與好友分享,增加樂趣。同時,分享也是直播間增長人氣,引爆流量的主要方式;
6、直播畫面高清流暢
直播畫面是影響觀眾觀感的條件,直播畫面追求高清流暢。目前主流的直播系統開發商的直播源碼一般支持720P的視頻流,客戶也可以根據自身要求提高相應的碼率,提高平台粉絲的觀看體驗,吸引粉絲;
7、送禮打賞功能
送禮打賞基本上是每個直播平台一定存在的功能,是主播與平台主要的經濟來源。送禮打賞也是增加主播與粉絲互動的一個重要方式,增加主播與粉絲的親密度;
開播/送禮打賞
8、美顏功能
美顏是直播系統中很重要的一個功能,也是主播吸引粉絲的一個很重要手段。美顏實際上是通過演算法識別圖像中的皮膚部分,對皮膚部分進行色值調整;
9、錄播回看
支持直播視頻的存儲、回放,讓粉絲不會錯過喜愛的主播;
10、自動鑒黃、快速停播
為了健康的直播環境,使用技術手段直播鑒黃是直播系統的必須環節。市場上目前提供的鑒黃方案有兩種:一種是截圖鑒黃,通常由業務系統接入鑒黃服務,如切斷視頻流、禁播等;另一種是與CDN結合,一對一直接對視頻流進行分析,實時性比較好,但成本較高一些。當然以上這些功能是直播平台應具備的基礎功能,基於強大的一對一直播系統源碼,只有實現了這些基礎功能,才會給用戶帶來直播互動體驗。
H. 如何通過直播源碼搭建視頻直播系統
下面整理了一些直播系統源碼搭建的直播平台基礎功能知識點介紹:
1.多終端同步功能:直播最初的誕生是在PC端,但是隨著手機移動端的飛速發展,,如今已經完全可以實現三端均可開播並觀看,即兩大主流手機操作系統Android、ios及PC三端互通功能,這也是現在的直播系統開發客戶的最基本需求。
2.多渠道注冊/登錄:目前隨著各種交友軟體的發展壯大,直播平台除了傳統的簡訊注冊登錄,QQ登錄之外,微信和微博也成為了直播系統不可或缺的注冊登錄方式,甚至是開播方式。
3.多渠道分享:類似與多渠道注冊登錄,分享的渠道也有QQ、微信、QQ空間、微信朋友圈、微博等。這樣也可以快速的進行宣傳。
4.多渠道充值/提取現金:如今微信支付與支付寶支付基本占據了整個移動支付的市場,因此一套優秀的直播系統源碼必定離不開這兩種支付方式介面,除此之外,能否接入四方支付介面也是考驗一套直播系統源碼的必要因素。
5直播畫面的高清流暢:直播室帶給客戶愉悅體驗的。目前主流的直播系統開發服務商的直播源碼一般支持720P的視頻流,當然客戶可以根據自身需求去提高相應碼率,為平台粉絲提供更為清晰流暢的直播體驗。
6. 聊天互動及彈幕功能:直播系統之所以這么火爆,得益於直播中的互動聊天、私信功能,能讓主播與粉絲之間進一步拉近距離。移動直播中的彈幕交互是用戶和主播互動的主要方式,實際上就是IM中的聊天室功能。聊天室和群聊功能類似,但聊天室的消息是不需要分發給不在線的用戶的,歷史消息也不需要查看,用戶只有進入聊天室後才能查看聊天消息和群成員信息。面對復雜多變的網路狀況,還需要根據用戶位置就近選擇近對應運營商的單線機房接入彈幕消息服務,讓彈幕更及時。
7. 錄播回看:支持直播視頻的存儲、回訪或者點播。
8..送禮打賞:禮物系統更是絕大多數移動直播平台的標配了,它是這些平台主要的收入來源。送禮物的形式也增強了用戶和主播之間的互動交流,也是主播依賴平台的最主要原因。禮物的收發在技術實現上也是用聊天室介面做的,通常採用IM中的自定義消息實現,當用戶收到或發送禮物時將自定義消息對應的禮物圖形渲染出來。
9.美顏特效功能:在這個「網紅經濟時代」,美顏功能不僅僅只在直播系統上得到了充分的應用,而且也在其他行業領域得以大展拳腳。美顏功能一般支持瘦臉、大眼、磨皮等基礎功能,這也是主播吸引粉絲的重要手段。
視頻直播源碼是搭建直播平台的基礎,決定著直播平台的優劣,建議需要搭建直播平台的朋友找一款優質的視頻直播源碼再進行搭建。
在這里推薦下夢網視頻雲為上市公司傾力打造,可以憑借雲上卓越的視頻技術及強大的基礎設施,為不同行業快速開通各類主流的視頻業務,甚至連某些種類APP都已預先開發好,客戶只需替換LOGO就可以上線一款直播產品。
I. 高分急求 Java 聊天室Socket 源代碼(精簡版 最重要的是能運行!!!)
這個應該可以的拉:
import java.applet.*;
import java.awt.*;
import java.io.*;
import java.net.*;
import java.awt.event.*;
public class ChatClient extends Applet{
protected boolean loggedIn;//登入狀態
protected Frame cp;//聊天室框架
protected static int PORTNUM=7777; //預設埠號7777
protected int port;//實際埠號
protected Socket sock;
protected BufferedReader is;//用於從sock讀取數據的BufferedReader
protected PrintWriter pw;//用於向sock寫入數據的PrintWriter
protected TextField tf;//用於輸入的TextField
protected TextArea ta;//用於顯示對話的TextArea
protected Button lib;//登入按鈕
protected Button lob;//登出的按鈕
final static String TITLE ="Chatroom applet>>>>>>>>>>>>>>>>>>>>>>>>";
protected String paintMessage;//發表的消息
public ChatParameter Chat;
public void init(){
paintMessage="正在生成聊天窗口";
repaint();
cp=new Frame(TITLE);
cp.setLayout(new BorderLayout());
String portNum=getParameter("port");//呢個參數勿太明
port=PORTNUM;
if (portNum!=null) //書上是portNum==null,十分有問題
port=Integer.parseInt(portNum);
//CGI
ta=new TextArea(14,80);
ta.setEditable(false);//read only attribute
ta.setFont(new Font("Monospaced",Font.PLAIN,11));
cp.add(BorderLayout.NORTH,ta);
Panel p=new Panel();
Button b;
//for login button
p.add(lib=new Button("Login"));
lib.setEnabled(true);
lib.requestFocus();
lib.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e){
login();
lib.setEnabled(false);
lob.setEnabled(true);
tf.requestFocus();//將鍵盤輸入鎖定再右邊的文本框中
}
});
//for logout button
p.add(lob=new Button ("Logout"));
lob.setEnabled(false);
lob.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
logout();
lib.setEnabled(true);
lob.setEnabled(false);
lib.requestFocus();
}
});
p.add(new Label ("輸入消息:"));
tf=new TextField(40);
tf.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
if(loggedIn){
//pw.println(Chat.CMD_BCAST+tf.getText());//Chat.CMD....是咩野來?
int j=tf.getText().indexOf(":");
if(j>0) pw.println(Chat.CMD_MESG+tf.getText());
else
pw.println(Chat.CMD_BCAST+tf.getText());
tf.setText("");//勿使用flush()?
}
}
});
p.add(tf);
cp.add(BorderLayout.SOUTH,p);
cp.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
//如果執行了setVisible或者dispose,關閉窗口
ChatClient.this.cp.setVisible(false);
ChatClient.this.cp.dispose();
logout();
}
});
cp.pack();//勿明白有咩用?
//將Frame cp放在中間
Dimension us=cp.getSize(),
them=Toolkit.getDefaultToolkit().getScreenSize();
int newX=(them.width-us.width)/2;
int newY=(them.height-us.height)/2;
cp.setLocation(newX,newY);
cp.setVisible(true);
paintMessage="Window should now be visible";
repaint();
}
//登錄聊天室
public void login(){
if(loggedIn) return;
try{
sock=new Socket(getCodeBase().getHost(),port);
is=new BufferedReader(new InputStreamReader(sock.getInputStream()));
pw=new PrintWriter(sock.getOutputStream(),true);
}catch(IOException e){
showStatus("Can't get socket: "+e);
cp.add(new Label("Can't get socket: "+e));
return;}
//構造並且啟動讀入器,從伺服器讀取數據,輸出到文本框中
//這里,長成一個線程來避免鎖住資源(lockups)
new Thread (new Runnable(){
public void run(){
String line;
try{
while(loggedIn &&((line=is.readLine())!=null))
ta.appendText(line+"\n");
}catch(IOException e){
showStatus("我的天啊,掉線了也!!!!");
return;
}
}
}).start();
//假定登錄(其實只是列印相關信息,並沒有真正登錄)
// pw.println(Chat.CMD_LOGIN+"AppletUser");
pw.println(Chat.CMD_LOGIN+"AppletUser");
loggedIn =true;
}
//模仿退出的代碼
public void logout(){
if(!loggedIn)
return;
loggedIn=false;
try{
if(sock!=null)
sock.close();
}catch(IOException ign){
// 異常處理哦
}
}
//沒有設置stop的方法,即使從瀏覽器跳到另外一個網頁的時候
//聊天程序還可以繼續運行
public void paint(Graphics g){
Dimension d=getSize();
int h=d.height;
int w=d.width;
g.fillRect(0,0,w,2);
g.setColor(Color.black);
g.drawString(paintMessage,10,(h/2)-5);
}
}
聊天室伺服器端
import java.net.*;
import java.io.*;
import java.util.*;
public class ChatServer{
//聊天室管理員ID
protected final static String CHATMASTER_ID="ChatMaster";
//系統信息的分隔符
protected final static String SEP=": ";
//伺服器的Socket
protected ServerSocket servSock;
//當前客戶端列表
protected ArrayList clients;
//調試標記
protected boolean DEBUG=false;
public ChatParameter Chat;
//主方法構造一個ChatServer,沒有返回值
public static void main(String[] argv){
System.out.println("Chat server0.1 starting>>>>>>>>>>>>>>>>");
ChatServer w=new ChatServer();
w.runServer();
System.out.println("***ERROR*** Chat server0.1 quitting");
}
//構造和運行一個聊天服務
ChatServer(){
Chat=new ChatParameter();
clients=new ArrayList();
try{
servSock=new ServerSocket(7777);//實有問題拉,不過可能是他自己定義既一個class.
System.out.println("Chat Server0.1 listening on port:"+7777);
}catch(Exception e){
log("IO Exception in ChatServer.<init>");
System.exit(0);
}
}
public void runServer(){
try{
while(true){
Socket us=servSock.accept();
String hostName=us.getInetAddress().getHostName();
System.out.println("Accpeted from "+hostName);
//一個處理的線程
ChatHandler cl=new ChatHandler(us,hostName);
synchronized(clients){
clients.add(cl);
cl.start();
if(clients.size()==1)
cl.send(CHATMASTER_ID,"Welcome!You are the first one here");
else{
cl.send(CHATMASTER_ID,"Welcome!You are the latest of"+
clients.size()+" users.");
}
}
}
}catch(Exception e){
log("IO Exception in runServer:"+e);
System.exit(0);
}
}
protected void log(String s){
System.out.println(s);
}
//處理會話的內部的類
protected class ChatHandler extends Thread {
//客戶端scoket
protected Socket clientSock;
//讀取socket的BufferedReader
protected BufferedReader is ;
//在socket 上發送信息行的PrintWriter
protected PrintWriter pw;
//客戶端出主機
protected String clientIP;
//句柄
protected String login;
public ChatHandler (Socket sock,String clnt)throws IOException {
clientSock=sock;
clientIP=clnt;
is=new BufferedReader(
new InputStreamReader(sock.getInputStream()));
pw=new PrintWriter (sock.getOutputStream(),true);
}
//每一個ChatHandler是一個線程,下面的是他的run()方法
//用於處理會話
public void run(){
String line;
try{
while((line=is.readLine())!=null){
char c=line.charAt(0);//我頂你老母啊 ,果只Chat.CMD咩xx冇定義 撲啊///!!!
line=line.substring(1);
switch(c){
//case Chat.CMD_LOGIN:
case 'l':
if(!Chat.isValidLoginName(line)){
send(CHATMASTER_ID,"LOGIN"+line+"invalid");
log("LOGIN INVALID from:"+clientIP);
continue;
}
login=line;
broadcast(CHATMASTER_ID,login+" joins us,for a total of"+
clients.size()+" users");
break;
// case Chat.CMD_MESG:
case 'm':
if(login==null){
send(CHATMASTER_ID,"please login first");
continue;
}
int where =line.indexOf(Chat.SEPARATOR);
String recip=line.substring(0,where);
String mesg=line.substring (where+1);
log("MESG: "+login+"--->"+recip+": "+mesg);
ChatHandler cl=lookup(recip);
if(cl==null)
psend(CHATMASTER_ID,recip+"not logged in.");
else
cl.psend(login,mesg);
break;
//case Chat.CMD_QUIT:
case 'q':
broadcast(CHATMASTER_ID,"Goodbye to "+login+"@"+clientIP);
close();
return;//ChatHandler結束
// case Chat.CMD_BCAST:
case 'b':
if(login!=null)
broadcast(login,line);
else
log("B<L FROM"+clientIP);
break;
default:
log("Unknow cmd"+c+"from"+login+"@"+clientIP);
}
}
}catch(IOException e){
log("IO Exception :"+e);
}finally{
//sock 結束,我們完成了
//還不能發送再見的消息
//得有簡單的基於命令的協議才行
System.out.println(login+SEP+"All Done");
synchronized(clients){
clients.remove(this);
if(clients.size()==0){
System.out.println(CHATMASTER_ID+SEP+
"I'm so lonely I could cry>>>>>");
}else if(clients.size()==1){
ChatHandler last=(ChatHandler)clients.get(0);
last.send(CHATMASTER_ID,"Hey,you are talking to yourself again");
}
else{
broadcast(CHATMASTER_ID,"There are now"+clients.size()+" users");
}
}
}
}
protected void close(){
if(clientSock==null){
log("close when not open");
return;
}
try{
clientSock.close();
clientSock=null;
}catch(IOException e){
log("Failure ring close to "+clientIP);
}
}
//發送一條消息給用戶
public void send(String sender,String mesg){
pw.println(sender+SEP+"*>"+mesg);
}
//發送私有的消息
protected void psend(String sender ,String msg){
send("<*"+sender+"*>",msg);
}
//發送一條消息給所有的用戶
public void broadcast (String sender,String mesg){
System.out.println("Broadcasting"+sender+SEP+mesg);
for(int i=0;i<clients.size();i++){
ChatHandler sib=(ChatHandler)clients.get(i);
if(DEBUG)
System.out.println("Sending to"+sib);
sib.send(sender,mesg);
}
if(DEBUG) System.out.println("Done broadcast");
}
protected ChatHandler lookup(String nick){
synchronized(clients){
for(int i=0;i<clients.size();i++){
ChatHandler cl=(ChatHandler)clients.get(i);
if(cl.login.equals(nick))
return cl;
}
}
return null;
}
//將ChatHandler對象轉換成一個字元串
public String toString(){
return "ChatHandler["+login+"]";
}
}
}
public class ChatParameter {
public static final char CMD_BCAST='b';
public static final char CMD_LOGIN='l';
public static final char CMD_MESG='m';
public static final char CMD_QUIT='q';
public static final char SEPARATOR=':';//?????
public static final int PORTNUM=7777;
public boolean isValidLoginName(String line){
if (line.equals("CHATMASTER_ID"))
return false;
return true;
}
public void main(String[] argv){
}
}