A. 如果用nodejs寫流媒體伺服器,那客戶端播放有什麼解決方案
這個問題其實跟伺服器具體用什麼技術實現無關,而主要跟流媒體的傳輸方式有關: 1.下載 2.流式傳輸
如果是下載方式,那麼一般就是基於http協議 如果是流式傳輸,那麼一般就是基於rtmp協議
所有這里需要關注具體的方式和協議,推薦的播放器(web端)有jwpalyer
後端一般用現成的伺服器:nginx 、red 5 、 flash media server 等
其中 red 5 為開源產品,支持 rtmp 協議,但目前版本對集群支持有一些問題~
B. nodejs可以接受tcp伺服器的數據嗎
nodejs中我們使用net模塊來創建tcp伺服器,tcp客戶端,實現伺服器與客戶端拍櫻宴之前的數據通信
創建tcp伺服器
var server=net.createServer([optations],[connectionListener])
optations:{allowHalfOpen:boolean}
allowHalfOpen:false 當伺服器接受到客戶端發送的一個FIN包時候,會回發一個FIN包,當為true時伺服器不會回FIN包,使得tcp伺服器可以繼續發送數據到客戶端,但是不會接受客戶端發送的數據,開發者必須調動end方法來關閉socket,默認是false
connectionListener:當客戶端與伺服器連接上了,可以觸發的回襲銀調函數。
function(socket){
//.......
}
我們也可以不用回調函數來寫連接上做什麼處理,連接上會觸發connection事件
var server=net.createServer()返回創建的tcp伺服器
我們可以server.on('connection',function(socket){
})
在創建完tcp伺服器我們通知伺服器要監聽客戶端連接
server.listen(port,[host],[backlog],[callback])
port:監聽的埠,為0時候tcp伺服器分配一個隨機的埠
host:監聽的ip和主機名,省略該參數,伺服器監聽任何ipv4地址的客戶端連接
backlog:指定等待隊列中最大的客戶端連接最大數量 默認511
當指定埠、ip這個時候伺服器開始監聽這個ip這個埠的客戶端了,這個時候觸發listening事件,可以指定callback參數來處理觸發listening具體要做什麼
我們也可以
server.on('lisening',function(){
//.......
})
創建一個tcp伺服器頌毀後可以用server.address()查看tcp伺服器監聽的信息
var address=server.address()
addres是一個對象
prot :監聽的埠
address:監聽的ip
family:ipv4還是ipv6
我們可以使用getConnections()查看與伺服器連接的客戶端的數量
server.getConnections(callback)
callback:function(err,count){
}
err:錯誤信息
count:為連接伺服器的數量
我們也可以設置最大的連接數,超過這個數字,伺服器不允許連接
server.maxConnections=2
伺服器關閉
server.close([callback])
這個 方法讓tcp伺服器拒絕新的客戶端連接,原有已經連上的客戶端是不關閉的,當所有的連接伺服器的客戶端關閉時候,伺服器默認自動關閉,觸發伺服器的close事件
下面我們寫一個tcp伺服器
var net=require("net");
opations={allowHalfOpne:false}
var server=net.createServer(opations);
server.on('connection',function(socket){
server.maxConnections=2;
console.log("伺服器最大連接數為%s",server.maxConnections)
server.getConnections(function(err,count){
console.log("已經有%s個客戶端連接",count)
})
console.log("%s客戶端與伺服器建立連接",server.address().address)
})
server.on('error',function(err){
throw err;
})
server.on('listening',function(){
console.log("伺服器開始監聽%j",server.address())
console.log("伺服器開始監聽")
})
server.listen(9966,'192.168.0.3');
setTimeout(function(){
server.close(function(){
console.log("tcp伺服器關閉11111")
})
console.log("tcp伺服器關閉")
},20000)
注意連接成功的時候觸發的connection事件,執行的方法,參數是一個socket埠對象,這個就是伺服器所監聽的埠對象,所以我們socket.address().address返回給我們的是監聽ip
socket埠對象
port:埠
address:ip
family:ipv4 ipv6
socket埠對象,可以讀取客戶端發送的流數據,每次接收到客戶端發送的數據觸發data事件。
接受客戶端發送的消息(在連接成功的觸發函數中 讓server監聽data事件做相應的處理)
server.on('connection',function(socket){
socket.on('data',function(data){
socket.setEncoding("utf-8");
console.log(data)
//console.log(data.toString())
})
})
bytesRead為socket埠對象監聽客戶端發送的數據位元組數
console.log(socket.bytesRead)
當客戶端關閉時候,觸發socket埠對象的end事件
我們把客戶端連接發送的數據保存到一個文件下
var net=require("net");
var fs=require("fs");
var server =net.createServer();
var op={
flags:"a",
encoding:"utf-8"
}
var file=fs.createWriteStream('./socket.txt',op)
server.on('connection',function(socket){
socket.on('data',function(data){
file.write(data);
})
})
server.on('listening',function(){
console.log("監聽開始")
})
server.listen('1111','192.168.0.3')
以管道形式發送數據到文件
var net=require("net");
var fs=require("fs");
var server =net.createServer();
var op={
flags:"a",
encoding:"utf-8"
}
var file=fs.createWriteStream('./socket.txt',op)
server.on('connection',function(socket){
//socket.on('data',function(data){
// file.write(data);
//})
socket.pipe(file,{end:false});
socket.on("end",function(){
file.end("wanbi")
})
})
server.on('listening',function(){
console.log("監聽開始")
})
server.listen('1111','192.168.0.3')
tcp客戶端
創建tcp客戶端
var client =new net.socket([opations])
optation:fd 一個現有的socket埠對象文件描述
type :ipv4 、ipv6
allowHalfOpne:true、false
連接伺服器
client.connect(prot,[host],[callback])
host不指定默認為本地ip
回調函數表示連接上了做什麼
若沒有可以socket埠對象觸發connect事件
client.on("connect",function(){
})
當我們連接成功後客戶端伺服器端的socket埠對象有下面的屬性
remoteAddress、remotePort、localAddress、localPort
socket埠對象可以寫入伺服器、客戶端流數據
socket.write(data,[encodeing],[callback])
寫入數據少時候我們直接寫入緩存區,數據很多時候,緩存區滿了,我們要把數據寫入緩存隊列中,這個時候write(data) 返回false,觸發drain
我們可以用bufferSize看緩存隊列中有多少個位元組
socket.on("error",function(err){
})
當遇到error時候這個socket埠對象應該銷毀
socket.destory()
socket.end([data],[encoding])
這個方法表示我們要關閉socket埠對象,這個不是關閉伺服器的close方法,後者是關閉伺服器,實現的效果是不能讓客戶端連接了,前者是關閉連接(socket埠對象)
當我們使用伺服器的socket埠對象(連接客戶端得)的end(data,encoding)方法時候,會觸發客戶端socket埠對象end事件
伺服器:
socket.end('88');
客戶端會執行下面的代碼:
client.on("end",function(){
//......
})
伺服器端不會退出應用程序,即使所有的客戶端都斷開了,這個時候我們要server.unref(),退出程序,可以用server.ref()阻止程序退出.
當socket埠對象徹底關閉時候會觸發close事件,我們可以指定當埠對象關閉時候做的處理
socket.on(''close',faction(had_error){
if(had_error){}
else{}
})
socket.writtenBytes表示寫了多少個位元組
我們tcp伺服器與客戶端連接了,但是突然間有一個斷電了,來不及向另一端發送關閉連接的FIN包,這樣另一邊這個socket埠永遠處於連接狀態,我們用socket.setKeepAlive([enable],[inteval])定時向另一端發送監測包,
我們實現一個伺服器讀一個文件的信息,當有客戶單連接上,吧這個信息傳給客戶端,輸出在控制台
伺服器代碼
var net=require("net");
var fs=require("fs");
var server =net.createServer();
var op={
flags:"r",
encoding:"utf-8"
}
var file=fs.createReadStream('./socket.txt',op)
server.on('connection',function(socket){
file.on('data',function(data){
socket.write(data);
})
socket.on("end",function(){
file.end("wanbi")
})
})
server.on('listening',function(){
console.log("監聽開始")
})
server.listen('1111','192.168.0.3')
客戶端代碼
var net=require("net");
var client=new net.Socket();
client.connect(1111,'192.168.0.3')
client.on('connect',function(){
console.log("ok")
})
client.on("data",function(data){
console.log(data.toString())
})
C. node 怎麼在伺服器上運行
首先安裝node.js環境,windows可以直接下載安裝包,下一步到底就可以了~~linux可以使用不同發行版的包管理器(但通常版本都不是最新的),使用最新版本可以從官網下載壓縮包,然後解壓就可以了,運行node.js代碼只需要在命令行中運行node XXX.js(xxx.js為你的代碼文件,如果沒有將node添加到環境變數,則需要進入node的目錄在執行上述命令)~ok 貌似就是這樣了~
D. 使用node.js,實現一個簡單的介面伺服器的功能
varhttp=require('http');
varmysql=require('mysql');
varconnection=mysql.createConnection({
host:'localhost',
user:'me',
password:'secret',
});
//開始你的mysql連接
connection.connect();
varserver=http.createServer(function(req,res){
//如果你發一個GET到http://127.0.0.1:1337/test?a=1&b=2的話
varurl_info=require('url').parse(req.url,true);
//檢查是不是給/test的request
if(url_info.pathname==='/test'){
//把query用urlencode,這樣可以用post發送
varpost_data=require('querystring').stringify(url_info.query);
//post的option
varpost_options={
host:'localhost',
port:1337,
path:'/response_logic',
method:'POST',
headers:{
'Content-Type':'application/x-www-form-urlencoded',
'Content-Length':post_data.length
}
};
//發出post
varrequest_made=http.request(post_options,function(response_received){
varbuf_list=newArray();
response_received.on('data',function(data){
buf_list.push(data);
});
response_received.on('end',function(){
varresponse_body=Buffer.concat(buf_list);
res.end(response_body);
connection.query('insertinto.........',function(err,rows,fields){
//處理你的結果
});
});
});
//發出post的data
request_made.end(post_data);
}
//這個是用來回復上面那個post的,顯示post的數據以表示成功了。你要是有別的目標,自然不需要這一段。
else{
req.pipe(res);
}
});
server.listen(1337,'127.0.0.1');
//在server關閉的時候也關閉mysql連接
server.on('close',function(){
connection.end();
});
console.log('listeningonport1337');