ทำไมต้องใช้ RMI
ในโครงการนี้ ฉันคิดถึงวิธีการสื่อสารระหว่างไคลเอนต์และเซิร์ฟเวอร์หลายวิธี เนื่องจากฉันทำงานกับแอปพลิเคชันไคลเอนต์ที่หลากหลาย ในที่สุดฉันก็เลือกเทคโนโลยีระหว่าง RMI และ Java-sockets ในบรรดาวิธีเหล่านั้น RMI ความยืดหยุ่นไม่สูง ทั้งไคลเอนต์และเซิร์ฟเวอร์จะต้องเขียนด้วยภาษา Java แต่ใช้งานได้สะดวกกว่า ในทางกลับกัน java-sockets แม้ว่าจะมีความยืดหยุ่นมากกว่า แต่ก็จำเป็นต้องกำหนดโปรโตคอลการสื่อสารระหว่างเซิร์ฟเวอร์และไคลเอนต์ มันค่อนข้างลำบากหลังจากชั่งน้ำหนักหลายครั้ง ในที่สุดฉันก็เลือก RMI สำหรับการสื่อสารระหว่างเซิร์ฟเวอร์กับไคลเอ็นต์
ปัญหาการอัพโหลดไฟล์
ในกระบวนการใช้ java-rmi คุณจะต้องประสบปัญหาในการอัปโหลดไฟล์อย่างหลีกเลี่ยงไม่ได้ เนื่องจากสตรีมไฟล์ไม่สามารถส่งในรูปแบบ rmi ได้ (เช่น พารามิเตอร์วิธีการใน rmi ไม่สามารถเป็น FileInputStream และอื่นๆ ที่คล้ายกันได้) ดังนั้นเราจึงต้องเลือกการประนีประนอม วิธีที่ดีที่สุดคือใช้ FileInputStream ก่อนเพื่ออ่านไฟล์ลงในอาร์เรย์ Byte จากนั้นส่งผ่านอาร์เรย์ Byte นี้เป็นพารามิเตอร์ไปยังวิธี RMI จากนั้นเรียกคืนอาร์เรย์ Byte ไปยัง outputStream บนฝั่งเซิร์ฟเวอร์ เพื่อให้สามารถ ผ่าน RMI แล้ว มาถ่ายโอนไฟล์กันเถอะ
นอกจากนี้ยังมีข้อเสียที่ไม่สามารถตรวจสอบความถูกต้องของข้อมูลที่ส่งได้
ให้ฉันอธิบายด้วยตัวอย่างด้านล่าง
FileClient
คัดลอกรหัสรหัสดังต่อไปนี้:
แพ็คเกจ rmiupload;
นำเข้า java.io.BufferedInputStream;
นำเข้า java.io.File;
นำเข้า java.io.FileInputStream;
นำเข้า java.io.FileNotFoundException;
นำเข้า java.io.IOException;
นำเข้า java.net.MalformedURLException;
นำเข้า java.rmi.การตั้งชื่อ;
นำเข้า java.rmi.NotBoundException;
นำเข้า java.rmi.RemoteException;
FileClient คลาสสาธารณะ {
FileClient สาธารณะ () {
// TODO ต้นขั้วคอนสตรัคเตอร์ที่สร้างขึ้นอัตโนมัติ
-
โมฆะคงที่สาธารณะ main (String [] args) {
พยายาม {
FileDataService fileDataService = (FileDataService) Naming.lookup("rmi://localhost:9001/FileDataService");
fileDataService.upload("/Users/NeverDie/Documents/test.mp4", new FileClient().fileToByte("/Users/NeverDie/Music/test.mp4"));
} จับ (MalformedURLException | RemoteException | NotBoundException e) {
// TODO บล็อก catch ที่สร้างขึ้นอัตโนมัติ
e.printStackTrace();
-
-
//วิธีนี้มีความสำคัญมากกว่า ด้วยวิธีนี้ ชื่อไฟล์จะถูกแปลงเป็นอาร์เรย์ไบต์
ไบต์ส่วนตัว [] fileToByte (ชื่อไฟล์สตริง) {
ไบต์ [] b = โมฆะ;
พยายาม {
ไฟล์ไฟล์ = ไฟล์ใหม่ (ชื่อไฟล์);
b = ไบต์ใหม่ [(int) file.length()];
BufferedInputStream คือ = ใหม่ BufferedInputStream (FileInputStream ใหม่ (ไฟล์));
คือ.อ่าน(ข);
} จับ (FileNotFoundException จ) {
// TODO บล็อก catch ที่สร้างขึ้นอัตโนมัติ
e.printStackTrace();
} จับ (IOException จ) {
// TODO บล็อก catch ที่สร้างขึ้นอัตโนมัติ
e.printStackTrace();
-
กลับข;
-
-
FileDataService
แพ็คเกจ rmiupload;
นำเข้า java.net.URL;
นำเข้า java.rmi.Remote;
นำเข้า java.rmi.RemoteException;
อินเทอร์เฟซสาธารณะ FileDataService ขยายระยะไกล {
//ชื่อไฟล์ที่นี่ควรเป็นที่อยู่ที่เก็บไฟล์บนฝั่งเซิร์ฟเวอร์
การอัปโหลดโมฆะสาธารณะ (ชื่อไฟล์ String, ไบต์ [] ไฟล์) พ่น RemoteException;
-
FileDataService_imp
คัดลอกรหัสรหัสดังต่อไปนี้:
แพ็คเกจ rmiupload;
นำเข้า java.io.BufferedOutputStream;
นำเข้า java.io.File;
นำเข้า java.io.FileNotFoundException;
นำเข้า java.io.FileOutputStream;
นำเข้า java.io.IOException;
นำเข้า java.net.URL;
นำเข้า java.rmi.RemoteException;
นำเข้า java.rmi.server.RMIClientSocketFactory;
นำเข้า java.rmi.server.RMIServerSocketFactory;
นำเข้า java.rmi.server.UnicastRemoteObject;
FileDataService_imp คลาสสาธารณะขยาย UnicastRemoteObject ใช้งาน FileDataService {
FileDataService_imp สาธารณะ () พ่น RemoteException {
-
@แทนที่
การอัปโหลดโมฆะสาธารณะ (ชื่อไฟล์ String, ไบต์ [] fileContent) พ่น RemoteException {
ไฟล์ไฟล์ = ไฟล์ใหม่ (ชื่อไฟล์);
พยายาม {
ถ้า (!file.exists())
ไฟล์. createNewFile();
BufferedOutputStream os = BufferedOutputStream ใหม่ (FileOutputStream ใหม่ (ไฟล์));
os.write(เนื้อหาไฟล์);
} จับ (FileNotFoundException จ) {
// TODO บล็อก catch ที่สร้างขึ้นอัตโนมัติ
e.printStackTrace();
} จับ (IOException จ) {
// TODO บล็อก catch ที่สร้างขึ้นอัตโนมัติ
e.printStackTrace();
-
-
-
ไฟล์เซิร์ฟเวอร์
คัดลอกรหัสรหัสดังต่อไปนี้:
แพ็คเกจ rmiupload;
นำเข้า java.net.MalformedURLException;
นำเข้า java.rmi.การตั้งชื่อ;
นำเข้า java.rmi.RemoteException;
นำเข้า java.rmi.registry.LocateRegistry;
FileServer ระดับสาธารณะ {
FileDataService ไฟล์ DataService;
FileServer สาธารณะ () {
พยายาม {
fileDataService = ใหม่ FileDataService_imp();
ค้นหา Registry.createRegistry (9001);
Naming.rebind("rmi://localhost:9001/FileDataService", fileDataService);
} จับ (RemoteException e) {
// TODO บล็อก catch ที่สร้างขึ้นอัตโนมัติ
e.printStackTrace();
} จับ (MalformedURLException e) {
// TODO บล็อก catch ที่สร้างขึ้นอัตโนมัติ
e.printStackTrace();
-
-
-
* @param args
-
โมฆะคงที่สาธารณะ main (String [] args) {
ไฟล์เซิร์ฟเวอร์ใหม่();
-
-